java网络编程-并发服务端

上次的服务端一次只能接受一个客户端的连接,性能实在堪忧,我们对服务端进行了改造,

每接到一个客户端的请求,就新建一个线程,让新线程跟客户端进行交互,主线程可以继续等待其他客户端的连接。

服务端:

public class Server {
    public static void main(String[] args) throws Exception {
        System.out.println("==服务器的启动==");
        // 1.注册端口
        ServerSocket serverSocket = new ServerSocket(8888);
        while (true) {
        //2.每接收到客户端的连接,就新建一个线程进行处理
            Socket socket = serverSocket.accept();
            new ServerReadThread(socket).start();
            System.out.println(socket.getRemoteSocketAddress() + "上线!");
        }
    }

    static class ServerReadThread extends Thread {
        private Socket socket;

        public ServerReadThread(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            try {
                InputStream is = socket.getInputStream();
                //4.把字节输入流包装成自己需要的流进行数据的读取。
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                //5.循环读取数据并打印到屏幕
                String line;
                while ((line = br.readLine()) != null) {
                    System.out.println("收到:" + line);
                }
            } catch (IOException e) {
                System.out.println(socket.getRemoteSocketAddress() + "下线!");
                throw new RuntimeException(e);
            }
        }
    }
}

客户端代码不变:

public class Client {
    public static void main(String[] args) throws Exception {
        System.out.println("==客户端的启动==");
        // 1.创建一个Socket的通信管道,请求与服务端的端口连接。
        Socket socket = new Socket("127.0.0.1", 8888);
        // 2.从Socket通信管道中得到一个字节输出流。
        OutputStream os = socket.getOutputStream();
        // 3.把字节流改装成自己需要的流进行数据的发送
        PrintStream ps = new PrintStream(os);
        // 4.开始发送消息
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextLine()) {
            String msg = sc.nextLine();
            ps.println(msg);
            ps.flush();
        }
    }
}

虽然解决了一些问题,但还有一些不完美

1.每个Socket接收到,都会创建一个线程,线程的竞争、切换上下文影响性能;
2.每个线程都会占用栈空间和CPU资源;
3.并不是每个socket都进行IO操作,无意义的线程处理;
4.客户端的并发访问增加时。服务端将呈现1:1的线程开销,访问量越大,系统将发生线程栈溢出,线程创建失
败,最终导致进程宕机或者僵死,从而不能对外提供服务

posted @ 2023-02-28 10:02  Mars.wang  阅读(50)  评论(0)    收藏  举报