线程池参数
- corePoolSize:常驻核心线程数,大于0,本地任务执行完毕,核心线程不会被销毁
- maximumPoolSize:线程池能够容纳同时执行的最大线程数。待执行的线程数大于此值,需要放到缓存队列中
- keepAliveTime:线程池中线程的空闲时间,当空闲时间达到keepAliveTime值时,线程会被销毁,知道只剩下corePoolSize为止。当
allowCoreThreadTimeOut
变量设置为true时,核心线程超时后也会被回收 - unit:TimeUtil参数,例如:TimeUtil.SECONDS
- workQueue:缓存队列,当请求线程数大于corePoolSize时,线程会进入blockingQueue中
- threadFactory:线程工厂,用来生产一组相同任务的线程。线程池命名,Factory增加组名前缀
- handler:拒绝策略,当workQueue任务缓存区达到上限后且活动线程数大于maximumPoolSize时候,进行该策略处理请求
相关类
Executors
可以静态工厂创建三个线程池包装对象
ForkJoinPool
1.8之后开始提供
public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool
// 获取处理器核的数目 Runtime.getRuntime().availableProcessors()
(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
ThreadPoolExecutor
// 创建可伸缩的线程池
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
// 创建固定大小的线程池
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
使用cache还是fixed,如果任务不稳定使用cache,任务比较平稳使用fixed
估算公式:线程池大小=处理器的核的数目 * 期望CPU利用率 * W/C
W/C是等待时间与计算时间的比率
cache和fixed最大线程数都是Integer.MAX_VALUE,存在OOM异常,最后截取阿里巴巴开发手册的一段规范
// 创建单个线程的线程池
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
与newFixedThreadPool(1)的区别:
newSingleThreadExecutor返回的线程池对象是FinalizableDelegatedExecutorService类型,他其中没有serCoreSize方法,ThreadPoolExecutor中有这个方法,也就意味着fixed的线程池可以强转为ThreadPookExecutor然后进行coreSize改变,而newSingleThreadExecutor则不能强转,从而他的一个线程是不会改变的
ScheduledThreadPoolExecutor
支持定时及周期性的执行任务
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}