客户端为什么要引入多线程

Posted 知晓的老巢

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了客户端为什么要引入多线程相关的知识,希望对你有一定的参考价值。

聊天软件中,输入流和输出流在同一个线程内应该独立出来,彼此独立(这就要引入多线程)

package com.sxt.chat;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

public class Test {
    public static void main(String[] args) throws UnknownHostException, IOException {
        Socket client = new Socket("localhost",8888);
        BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
        //输入流(接收客户端发送过来的)
        DataInputStream dis = new DataInputStream(client.getInputStream());
        //输出流(发送给客户端)
        DataOutputStream dos = new DataOutputStream(client.getOutputStream());
        while(true){
            //给客户端发送过去
            String  msg =console.readLine();
            dos.writeUTF(msg);
            dos.flush();
            //输出客户端发送过来的
            String info = dis.readUTF();
            System.out.println(info);
            
        }
                
    }
}
从上面代码中我们知道,先要从客户端输入数据,再接收服务器端发送过来的信息,而在我们聊天软件中,接收数据和发送数据是独立的,从而我们可以把上面代码改成以下形式
package com.sxt.chat;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {
    public static void main(String[] args) throws UnknownHostException, IOException {
        Socket client = new Socket("localhost",8888);
        //一条路径
        new Thread(new Send(client)).start();;
        new Thread(new Receive(client)).start();;
    }
}
发送数据的代码如下:
package com.sxt.chat;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

public class Send implements Runnable{
    //从控制台输入
    private BufferedReader console ;
    //输出流(发送给服务器端)
    private DataOutputStream dos ;
    //标志位
    private boolean  isRunning = true;
    public Send(){
      console = new BufferedReader(new InputStreamReader(System.in));
    }
    public Send(Socket client){
        this();
        try {
            dos = new DataOutputStream(client.getOutputStream());
        } catch (IOException e) {
            isRunning =  false;
            CloseUtil.closeAll(dos,console);
        }
        
    }
    /*
     *从控制台接收数据
     */
    public String getMsgFromConsole(){
        try {
            return console.readLine();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return "";
    }
    /*
     *从控制台接收数据
     */
    public void send(){
        String msg = getMsgFromConsole();
        if(null!=msg&&!msg.equals("")){
            try {
                dos.writeUTF(msg);
                dos.flush();
            } catch (IOException e) {
                isRunning = false;
                CloseUtil.closeAll(dos,console);
            }
        }
    }
    @Override
    public void run() {
        while(isRunning){
            send();
        }
    }

}

接收数据的代码如下:

package com.sxt.chat;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;


public class Receive implements Runnable{
    //输入流(接收服务器端发送过来的)
    private DataInputStream dis ;
    //标志符
    private boolean isRunning = true;
    public Receive(){
        
    }
    public Receive(Socket client){
        this();
        try {
            dis = new DataInputStream(client.getInputStream());
        } catch (IOException e) {
            
        }
    }
    public String receive(){
        String msg = "";
        try {
            msg = dis.readUTF();
        } catch (IOException e) {
            isRunning = false;
            CloseUtil.closeAll(dis);
        }
        return msg;
    } 
    @Override
    public void run() {
        while(isRunning){
            System.out.println(receive());
        }
    }

}

关闭流数据代码如下:

package com.sxt.chat;

import java.io.Closeable;
import java.io.IOException;

public class CloseUtil {
    public static void closeAll(Closeable... io){
        for(Closeable temp :io){
            if(null!=temp){
                try {
                    temp.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}

服务器代码如下:

package com.sxt.chat;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(8888);
        Socket client = server.accept();
        //输入流(接收客户端发送过来的)
        DataInputStream dis = new DataInputStream(client.getInputStream());
        //输出流(发送给客户端)
        DataOutputStream dos = new DataOutputStream(client.getOutputStream());
        while(true){
            //输出客户端发送过来的
            String msg = dis.readUTF();
            System.out.println(msg);
            //给客户端发送过去
            dos.writeUTF("服务器===》"+msg);
            dos.flush();
        }
    }
}

 

 

以上是关于客户端为什么要引入多线程的主要内容,如果未能解决你的问题,请参考以下文章

2023-05-30:Redis6.0为什么要引入多线程呢?

多线程 Thread 线程同步 synchronized

多个请求是多线程吗

11操作系统之线程概念与多线程模型

JAVA知识每日一问:Redis6.0为什么引入多线程?

利用多线程实现Future模式