zoukankan      html  css  js  c++  java
  • 多线程笔记

    BIO的时候, 一个客户端对应服务器的一条线程, 比较耗线程资源.

    在此基础上, 对起线程进行优化, 创建一个线程池, 对线程进行管理, 可以设置一个最大线程数 maxThreadCount. 这样, 达到线程可控的目的.

    即使外面有远大于线程数的连接过来, 也不至于让服务器撑爆.

    多出的客户端, 就进入线程池的队列中排队.

    伪异步IO 是Netty权威指南里面提到的, 并不是一个公认的说法或者官方的说法.

    这里只需要修改服务端的代码即可:

    server:

    public class Server implements Runnable {
    
        private Socket socket;
    
        public Server(Socket socket) {
            this.socket = socket;
        }
    
        @Override
        public void run() {
            BufferedReader in = null;
            PrintWriter out = null;
    
            try {
                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                out = new PrintWriter(socket.getOutputStream(), true);
                System.out.println("server : 客户端接入" + socket.toString());
    
                while (true) {
                    String msg = in.readLine();
                    if (msg == null) {
                        break;
                    }
                    System.out.println("from client : " + msg);
                    if (msg.equals("几点了")) {
                        out.println(new DateTime(2020,1,1,1,1,1).toString("yyyy-MM-dd HH:mm:ss"));
                    }
                    else{
                        out.println("没看懂...");
                    }
                }
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            finally {
                if (in != null) {
                    try {
                        in.close();
                    }
                    catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (out != null) {
                    out.close();
                }
                if (this.socket != null) {
                    try {
                        this.socket.close();
                    }
                    catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        public static void main(String[] args) throws Exception {
            final ServerSocket serverSocket = new ServerSocket(1234);
            try {
                int maxPoolSize = 100;
                ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                        Runtime.getRuntime().availableProcessors(),
                        maxPoolSize,
                        120L,
                        TimeUnit.SECONDS,
                        new ArrayBlockingQueue<Runnable>(1000)
                );
                System.out.println("服务器启动, 开始监听 1234 端口");
                Socket socket = serverSocket.accept();
                System.out.println("监听到一个连接");
                threadPool.execute(new Server(socket));
            }
            finally {
                serverSocket.close();
            }
        }
    }

    我这里直接在main 方法里面, 创建了一个自定义线程池, 并放了一个长度为 1000 的有界队列进去.

    客户端代码不变

    clientA:

    public class ClientA {
        public static void main(String[] args) throws IOException {
            //与服务器建立连接
            Socket socket = new Socket("127.0.0.1", 1234);
            BufferedReader in = null;
            PrintWriter out = null;
    
            try {
                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                out = new PrintWriter(socket.getOutputStream(), true);
    
                out.println("几点了");
    
                while (true) {
                    String serverMsg = in.readLine();
                    if(serverMsg == null){
                        break;
                    }
                    System.out.println("from server : " + serverMsg);
                }
            }
            finally {
                if (in != null) {
                    try {
                        in.close();
                    }
                    catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (out != null) {
                    out.close();
                }
                if (socket != null) {
                    try {
                        socket.close();
                    }
                    catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    结果也是不变的:

    clientA:

    server:

    这种方式任然是一种阻塞的方式.

    参考:

    Netty权威指南

  • 相关阅读:
    docker-machine create ,,,
    docker run with zabbix3.0
    mysql 官网
    取模性质
    欧涛最短路【记录最短路径】
    P4568 飞行路线【分层图最短路】
    CCF201403 无线网络【限制型最短路】
    POJ2449 【第k短路/A*】
    Feeding Time 【bfs求最大连通块】
    printf特殊用法
  • 原文地址:https://www.cnblogs.com/elvinle/p/12388427.html
Copyright © 2011-2022 走看看