暑期JAVA学习(42.1)TCP通信——使用线程池优化

一、目前的通信架构模型

在这里插入图片描述

目前的通信架构存在什么问题?

●客户端与服务端的线程模型是: N-N的关系。

●客户端并发越多,系统瘫痪的越快。

二、引入线程池处理多个客户端消息

在这里插入图片描述

本次使用线程池的优势在哪里?

●服务端可以复用线程处理多个客户端,可以避免系统瘫痪。

●适合客户端通信时长较短的场景。

三、具体实现

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

/**
 拓展:使用线程池优化:实现通信。
 */
public class ClientDemo01 {
    public static void main(String[] args) {
        try {
            System.out.println("===客户端启动===");
            // 1、创建Socket通信管道请求有服务端的连接
            // public Socket(String host, int port)
            // 参数一:服务端的IP地址
            // 参数二:服务端的端口
            Socket socket = new Socket(InetAddress.getLocalHost(),6666);

            // 2、从socket通信管道中得到一个字节输出流 负责发送数据
            OutputStream os = socket.getOutputStream();

            // 3、把低级的字节流包装成打印流
            PrintStream ps = new PrintStream(os);

            Scanner sc = new Scanner(System.in);
            while (true) {
                System.out.println("请说:");
                String msg = sc.nextLine();
                // 4、发送消息
                ps.println(msg);
                ps.flush();
            }

            // 关闭资源。注意哦,不用时才关,不要随便关
            // socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
/**
 目标:实现服务端可以同时处理多个客户端的消息。
 */
public class ServerDemo2 {

    //使用静态变量记住一个线程池对象
    //    public ThreadPoolExecutor(int corePoolSize,
    //                              int maximumPoolSize,
    //                              long keepAliveTime,
    //                              TimeUnit unit,
    //                              BlockingQueue<Runnable> workQueue,
    //                              RejectedExecutionHandler handler)
    //参数一:指定线程池的线程数量(核心线程): corePoolSize
    //参数二:指定线程池可支持的最大线程数: maximumPoolSize
    //参数三:指定临时线程的最大存活时间: keepAliveTime
    //参数四:指定存活时间的单位(秒、分、时、天): unit
    //参数五:指定任务队列: workQueue
    //参数六:指定用哪个线程工厂创建线程: threadFactory
    //参数七:指定线程忙,任务满的时候,新任务来了怎么办: handler

    private static ExecutorService pool = new ThreadPoolExecutor(3,
            5,6, TimeUnit.SECONDS,new ArrayBlockingQueue<>(2),
            Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());

    public static void main(String[] args) {
        try {
            System.out.println("===服务端启动成功===");
            // 1、注册端口
            ServerSocket serverSocket = new ServerSocket(6666);
            // a.定义一个死循环由主线程负责不断的接收客户端的Socket管道连接。
            while (true) {
                // 2、每接收到一个客户端的Socket管道,交给一个独立的子线程负责读取消息
                Socket socket = serverSocket.accept();
                System.out.println(socket.getRemoteSocketAddress()+ "上线啦!");
                Runnable target = new ServerReaderRunnable(socket);
                pool.execute(target);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
public class ServerReaderRunnable implements Runnable{
    private Socket socket;
    public ServerReaderRunnable(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        try {
            // 3、从socket通信管道中得到一个字节输入流
            InputStream is = socket.getInputStream();
            // 4、把字节输入流包装成缓冲字符输入流进行消息的接收
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            // 5、按照行读取消息
            String msg;
            while ((msg = br.readLine()) != null){
                System.out.println(socket.getRemoteSocketAddress() + "说: " + msg);
            }
        } catch (Exception e) {
            System.out.println(socket.getRemoteSocketAddress() + "下线啦!");
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呦呦呦欸哟哟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值