为什么不建议使用Executors创建线程池?
JDK为我们提供了Executors线程池工具类,里面有默认的线程池创建策略,大概有以下几种:
-
定长线程池 FixedThreadPool:线程池线程数量固定,即corePoolSize和maximumPoolSize数量一样。
-
单线程池 SingleThreadPool:单个线程的线程池。
-
可缓存线程池 CachedThreadPool:初始核心线程数量为0,最大线程数量为Integer.MAX_VALUE,线程空闲时存活时间为60秒,并且它的阻塞队列为SynchronousQueue,它的初始长度为0,这会导致任务每次进来都会创建线程来执行,在线程空闲时,存活时间到了又会释放线程资源。
-
定时线程池 ScheduledThreadPool:用于执行定时任务或周期性任务。
虽然用Executors工具类方便,但是阿里巴巴开发手册强制不允许使用Executors来创建线程池,原因在于:(摘自阿里编码规约)
线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,
规避资源耗尽的风险。说明:Executors各个方法的弊端:newFixedThreadPool和newSingleThreadExecutor: 主要问题是堆积的请
求处理队列可能会耗费非常大的内存,甚至OOM。newCachedThreadPool和newScheduledThreadPool: 主要问题是线程数最大数
是Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至OOM。
我们从JDK源码中寻找一波答案:java.util.concurrent.Executors:
// FixedThreadPool
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
// SingleThreadPool
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
// CachedThreadPool
public static ExecutorService newCachedThreadPool() {
// 允许创建线程数为Integer.MAX_VALUE
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
// ScheduledThreadPool
public ScheduledThreadPoolExecutor(int corePoolSize) {
// 允许创建线程数为Integer.MAX_VALUE
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}
public LinkedBlockingQueue() {
// 允许队列长度最大为Integer.MAX_VALUE
this(Integer.MAX_VALUE);
}
从JDK源码可看出,Executors工具类无非是把一些特定参数进行了封装,并提供一些方法供我们调用而已,我们并不能灵活地填写参数,策略过于简单,不够友好。
CachedThreadPool和ScheduledThreadPool最大线程数为Integer.MAX_VALUE,如果线程无限地创建,会造成OOM异常。
LinkedBlockingQueue基于链表的FIFO队列,是无界的,默认大小是Integer.MAX_VALUE,因此FixedThreadPool和SingleThreadPool的阻塞队列长度为Integer.MAX_VALUE,如果此时队列被无限地堆积任务,会造成OOM异常。
以上是“为什么不建议使用Executors创建线程池”这篇文章的所有内容,感谢各位的阅读!

浙公网安备 33010602011771号