JAVA 线程池与NIO Socket链接

JAVA线程池

核心类 ThreadPoolExecutor,实例化需要指定一个队列。
跟Tomcat一样,有一个固定数量线程的线程池并且有一个请求队列,当
处理请求的线程已经用完时(所有线程处于工作状态时),所有请求都会放在队列中,而ThreadPoolExecutor也是一个道理。

//实例化一个只能存放3个请求的线程
 BlockingQueue queue = new ArrayBlockingQueue(3);
//实例化一个最多2条用于处理请求线程,当线程池用完其他请求会存放在queue 中
 ExecutorService executor = new ThreadPoolExecutor(1, 2, 1, TimeUnit.DAYS, queue);

//注意ThreadPoolExecutor实例化所需要队列接口为BlockingQueue 
//表示同一时间只会有一个请求放到队列中

定义请求处理器(即请求)

class Handler implements Runnable {
        @Override
        public void run() {
            log("处理请求代码");
        }
    }

执行请求处理

Handler  handler = new Handler();
//如果当前线程池所有线程都用完时,该handler不会被执行,直到有空闲的线程时。
executor.execute(handler);

NIO Socket服务端

那么问题来了,配合NIO Socket循环接受连接
就会有可能导致
连接长时间处于连接而同时又是待处理状态:

while (true) {
 log("Start accept");
 SocketChannel socketChannel = serverSocketChannel.accept();
            if (socketChannel == null) {
                log("new Connection is null");
            } else {
                log("new Connection,ip:%s", socketChannel.getRemoteAddress());
                OnConnection connection = new OnConnection(socketChannel);
                //当线程用完时,连接会被放到队列queue中,直到线程池中有空闲的线程
                //如果这些客户端连接一直处于等待而不断开连接状态,那么queue会一直被堆满,
                //并且由于连接没有释放导致内存一直积压
                executor.execute(connection);
            }
}

所以一个合理的C/S交互是应该设计超时策略,当超时时间内对方(S或C)无法响应,则应该断开连接。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、多线程 说明下线程的状态 java中的线程一共有 5 种状态。 NEW:这种情况指的是,通过 New 关键字创...
    Java旅行者阅读 4,738评论 0 44
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,973评论 19 139
  • 前言 线程池是Java中的一个重要概念,从Android上来说,当我们跟服务端进行数据交互的时候我们都知道主线程不...
    老实任阅读 1,275评论 1 9
  • 曾经我认为爱一个人,就是一定要想办法将对方留在身边。因为如果无法待在心爱的人身边,那么你要如何给她幸福? 但是...
    HuilingLee阅读 1,116评论 0 1
  • 简述 Kotlin同java一样也是一门面向对象的语言,作为比java更高级的语言,当然有它独有的特点: *构造函...
    i校长阅读 921评论 7 6