合理的设置线程池队列长度
0 概述
在实际工作中,经常会用到线程池,那么如何设置线程池队列长度,如果长度设置的不合理就无法发挥出多线程的威力。那么队列长度究竟应该设置多大呢?其实要取决于使用场景;比如你是全程异步的系统你的队列设置为0,corePoolSize设置为cpu核数。本文主要通过研究tomcat、Dubbo等业界成熟的产品是如何设置线程队列的,然后分析究竟如何合理的设置线程池队列长度。
1 JDK线程池策略
先增加线程至corePoolSize,之后放入队列,如队列满则增加线程至maximumPoolSize。具体可以参考: 其实我们不难发现如何队列长度设置无限长度,那么线程池个数将只会增加到corePoolSize ,如果corePoolSize个数设置又过小,这样就会无法发挥出多线程的威力。
2 Tomcat线程池策略
Tomcat的线程池队列是无限长度的,但是线程池会一直创建到maximumPoolSize,然后才把请求放入等待队列中
tomcat 任务队列org.apache.tomcat.util.threads.TaskQueue其继承与LinkedBlockingQueue,覆写offer方法。
@Override
public boolean offer(Runnable o) {
//we cant do any checks
if (parent==null) return super.offer(o);
//we are maxed out on threads, simply queue the object
if (parent.getPoolSize() == parent.getMaximumPoolSize()) return super.offer(o);
//we have idle threads, just add it to the queue
if (parent.getSubmittedCount()<(parent.getPoolSize())) return super.offer(o);
//线程个数小于MaximumPoolSize会创建新的线程。
//if we have less threads than maximum force creation of a new thread
if (parent.getPoolSize()<parent.getMaximumPoolSize()) return false;
//if we reached here, we need to add it to the queue
return super.offer(o);
}
2 Dubbo线程池策略
Dubbo 提供3种线程池模型即:FixedThreadPool、CachedThreadPool(客户端默认的)、LimitedThreadPool(服务端默认的),从源码可以看出,其默认的队列长度都是0,当队列长度为0 ,其使用是无缓冲的队列SynchronousQueue,当运行线程超过maximumPoolSize则拒绝请求。
3 总结
-
线程池的任务队列本来起缓冲作用,但是如果设置的不合理会导致线程池无法扩容至max,这样无法发挥多线程的能力,导致一些服务响应变慢。 队列长度要看具体使用场景,取决服务端处理能力以及客户端能容忍的超时时间等 建议采用tomcat的处理方式,core与max一致,先扩容到max再放队列,不过队列长度要根据使用场景设置一个上限值,如果响应时间要求较高的系统可以设置为0。
