多线程实例---远程聊天室(教你了了百行搭建聊天室)

前言:这是在以往学习过程当中,老师教授咱们的一个简单的聊天室的示例,温故而知新嘛,有不少本身当时没有懂为何要这样写的那些代码,在如今倒是以为当是如此。学习都同样即要不断地向前学习,也不要忘了,有好多东西须要巩固
下面来讲聊天室:java

ChatServer

package day17;
 
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
 
public class ChatServer {
private ArrayList<TongXinThread> list =
        new ArrayList<>();
public void launch() {
    //启动服务线程
    new Thread() {
        @Override
        public void run() {
           try {
              ServerSocket ss = new ServerSocket(8000);
              System.out.println("聊天室服务器已启动");
              while(true) {
                 Socket s = ss.accept();
                 TongXinThread t =
                  new TongXinThread(s);
                 t.start();
              }
           } catch (Exception e) {
              System.out.println(
               "服务没法在 8000 端口上启动,或服务已经中止");
           }
        }
    }.start();
}
class TongXinThread extends Thread {
    Socket s;
    BufferedReader in;
    PrintWriter out;
    private String name;
    public TongXinThread(Socket s) {
        this.s = s;
    }
   
    public void send(String msg) {
        out.println(msg);
        out.flush();
    }
   
    public void sendAll(String msg) {
        synchronized (list) {
           for (TongXinThread t : list) {
              t.send(msg);
           }
        }
    }
   
    @Override
    public void run() {
        try {
           //UTF-8, 换行
           in = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8"));
           out = new PrintWriter(new OutputStreamWriter(s.getOutputStream(),"UTF-8"));            
           //接收客户端的昵称
           this.name = in.readLine();
           //把当前通讯线程实例,加入集合
           synchronized (list) {
              list.add(this);
           }
           //发送欢迎信息
           send("欢迎进入激情聊天室");
           //群发上线消息
           sendAll(name+"进入了聊天室,在线人数:"+list.size());
          
           String line;
           while((line = in.readLine()) != null) {
              sendAll(name+"说:"+line);
           }
           //断开
        } catch (Exception e) {
           //断开
        }
        //删除当前通讯线程实例
        synchronized (list) {
           list.remove(this);
        }
        //群发离线消息
        sendAll(name+"离开了聊天室,在线人数:"+list.size());
       
       
    }
}
public static void main(String[] args) {
    ChatServer s = new ChatServer();
    s.launch();
}
}

ChatClient

package day17;
 
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.LinkedList;
import java.util.Scanner;
 
public class ChatClient {
private Socket s;
private BufferedReader in;
private PrintWriter out;
private String name;
private LinkedList<String> list = new LinkedList<>();
private boolean flag; //开关
public void launch() {
    try {
        s = new Socket("192.168.21.61", 8000);
        in = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8"));
        out = new PrintWriter(new OutputStreamWriter(s.getOutputStream(),"UTF-8"));              
        //昵称
        System.out.print("起一个昵称: ");
        name = new Scanner(System.in).nextLine();
        out.println(name);
        out.flush();
       
        //接收线程
        new Thread() {
           @Override
           public void run() {
              receive();
           }
        }.start();
       
        //输入线程
        new Thread() {
           @Override
           public void run() {
              input();
           }
        }.start();
       
        //打印线程
        new Thread() {
           @Override
           public void run() {
              print();
           }
        }.start();
       
    } catch (Exception e) {
        System.out.println("没法链接聊天室服务器");
        e.printStackTrace();
    }
}
protected void print() {
    while(true) {
        synchronized (list) {
           while (list.isEmpty() || flag) {
              try {
                 list.wait();
              } catch (InterruptedException e) {
              }
           }
           String msg = list.removeFirst();
           System.out.println(msg);
        }
    }
}
 
protected void input() {
    System.out.println("按回车输入聊天内容");
   
    while(true) {
        new Scanner(System.in).nextLine();
        flag = true;//打开开关
       
        System.out.print("输入聊天内容:");
        String s = new Scanner(System.in).nextLine();
        out.println(s);
        out.flush();
       
        flag = false;//关闭开关
        //通知打印线程能够继续打印
        synchronized (list) {
           list.notify();
        }
    }
}
 
protected void receive() {
    try {
        String line;
        while((line = in.readLine()) != null) {
           synchronized (list) {
              list.add(line);
              //通知打印线程已经有数据能够打印了
              list.notify();
           }
        }
    } catch (Exception e) {
    }
    System.out.println("已经与服务器断开链接");
}
 
public static void main(String[] args) {
    ChatClient c = new ChatClient();
    c.launch();
}
}