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 @   Mars.wang  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
历史上的今天:
2019-02-28 impala学习笔记
点击右上角即可分享
微信分享提示