`

关注 Java 线程池的任务队列长度

阅读更多

 

Java 5.0 就开始自带线程池的实现,其中固定大小的线程池,对普通使用还是很好用的。就是 Executors.newFixedThreadPool ,指需要指定一个大小数目就可以。相对于其他几种方式,易于实现高效稳定的服务器。

 

但是好用归好用,一些需要非常细心的问题,还是需要关注的,尤其是高并发场景,7*24不间断运行场景下。本文就是把这些地方记录下来,在设计和实现时,在这些问题上务必不能马虎,因为这关系到稳定性和效率,且不易通过测试来排查。

 

(1)实现:

 

几种线程池,都是通过  ThreadPoolExecutor 来实现的,如下:

 

  1. ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,long keepAliveTime, TimeUnit unit,BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler)  

 

 

newFixedThreadPool :

 

  public static ExecutorService newFixedThreadPool(int paramInt)
  {
    return new ThreadPoolExecutor(paramInt, paramInt, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());
  }

 

而 LinkedBlockingQueue的实现:

 

  public LinkedBlockingQueue()
  {
    this(2147483647);
  }

 

这个默认的构造函数,实际上是有一些问题的(实际是构造了一个大小为 Integer.MAX_VALUE的任务队列)。

 

(2)问题

我们设想一个场景,客户端/服务器工作模式,请求来得很快,服务器端accept之后,将Socket放到了任务队列中,读请求处理,并发送响应。客户端连接来得很快,但处理没有那么快(例如需要IO或大量数学运算),所以来了之后就都排在队列里。一直到2147483647。

 

但是实际上,如果一个新的任务排在第100甚至1000、10000,客户端都可以等待,但是如果排到了 1000,000,客户端还会等待着吗?就像你如果去银行办业务,眼看排队都排到街上了,今天肯定轮不到了,你还会继续等吗?

 

换成计算机的设计语言,客户端连接,按照约定俗成,都是有超时的,开始提交了请求自然会等待,一定时间内得不到响应就超时进入异常处理流程了,那么,服务器队列里那个Socket还有什么意义呢?

 

(3)结论

 

所以说,在设计时,队列的长度是一定要用心设计和考虑的,除了在Demo和简单测试一下的程序里,不要轻易而简单的使用newFixedThreadPool ,要想清楚它的问题,在使用时使用其它方式避免。

 

一般情况下,队列的大小遵循下面的公事:

 

 queSize <= ClientTimeOut(秒) * TPS

 

队列大小 小于等于 客户端超时 * 每秒处理的交易数

 

当然,这些数据都是估算,另外,也取决于你做的东西,对于客户端超时早就走了,服务器端还得处理这种情况是一种什么态度和需求。

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    Java 4种线程池的使用

    Java通过Executors提供四种线程池,分别为:  newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。  newFixedThreadPool 创建一个定长线程池...

    百度地图开发java源码-wtp:WTP-一个可靠的线程池管理系统

    百度地图开发java源码 WTP - A reliable thread ...统计线程池运行状态,活跃线程数、最大创建线程数、队列长度、队列剩余长度、队列排队长度、任务完成数、任务完成平均时间、发生rejected次数、r

    第7章-JUC多线程v1.1.pdf

    如果当前线程池中的线程数目&gt;=corePollSize, 则每来一个任务, 会尝试将其添加到缓冲队列中, 如果添加成功, 则该任务会等待空闲线程将其取出去执行, 如果添加失败(一般是以为任务队列已经满了), 则会尝试创建新的线程...

    Java-ThreadPools

    用户初始化一个线程池,然后提交由池中线程处理的任务(以毫秒为单位的指定长度)。 处理任务时,它会附加到日志文件和 GUI 上的文本区域。 由于有许多线程写入同一个文件,可能是在同一时间,因此采用了同步方法。...

    Java并发编程(学习笔记).xmind

    如果队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池会抛出异常,告诉调用者“我不能再接受任务了” keepAliveTime 保持存活时间,当线程数大于corePoolSize的空闲线程能...

    Executor,Executors,ExecutorService比较.docx

    Executors: 是java.util.concurrent包下的一个类,提供了若干个静态方法,用于生成不同类型的线程池。Executors一共可以创建下面这四类线程池: 1.newFixedThreadPool创建一个可缓存线程池,如果线程池长度超过...

    JAVA 范例大全 光盘 资源

    实例132 执行任务(线程池) 378 实例133 碰撞的球(多线程) 382 实例134 钟表(多线程) 387 实例135 模拟生产者与消费者 392 实例136 仿迅雷下载文件 396 第15章 图形编程 403 实例137 多变的按钮 403 ...

    Java JDK实例宝典

    全部代码出自电子工业出版社夏先波的《Java JDK实例宝典》一书,本书以J2SE 5.0为开发环境,选取Java应用的典型实例,循序渐进地介绍了Java语言的各种开发方法和技巧,实例代码注释详细规范,思路清晰。 第1章 ...

    java范例开发大全源代码

     实例149 简单的长度单位转换类 227  实例150 卡车和卡车司机之间的关系 229  实例151 双色球 231  8.2 成员变量和方法 236  实例152 使用类作为成员变量 236  实例153 构造方法 237  实例154 ...

    java范例开发大全

    实例242 手术任务(线程池) 462 实例243 模拟人工服务台(线程连接池) 466 13.6 线程应用实例 471 实例244 下雪的村庄 472 实例245 小飞侠 474 实例246 飞流直下 477 实例247 多线程断点续传 479 实例248 滚动的...

    Java范例开发大全 (源程序)

     实例149 简单的长度单位转换类 227  实例150 卡车和卡车司机之间的关系 229  实例151 双色球 231  8.2 成员变量和方法 236  实例152 使用类作为成员变量 236  实例153 构造方法 237  实例154 使用静态...

    Java范例开发大全(全书源程序)

    实例242 手术任务(线程池) 462 实例243 模拟人工服务台(线程连接池) 466 13.6 线程应用实例 471 实例244 下雪的村庄 472 实例245 小飞侠 474 实例246 飞流直下 477 实例247 多线程断点续传 479 实例248 ...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    书名:《Java开发实战1200例(第I卷)》(清华大学出版社.李钟尉,陈丹丹) PDF格式扫描版,全书分为24章,共817页。2011年1月出版。 全书压缩打包成4部分,这是第3部分 注:本系列图书的第I、II卷再版时均相应改名为...

    java范例开发大全(pdf&源码)

    实例242 手术任务(线程池) 462 实例243 模拟人工服务台(线程连接池) 466 13.6 线程应用实例 471 实例244 下雪的村庄 472 实例245 小飞侠 474 实例246 飞流直下 477 实例247 多线程断点续传 479 实例248 滚动的...

Global site tag (gtag.js) - Google Analytics