
规则
线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,合理设置7大参数。
这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
线程池不允许使用 Executors 去创建的原因
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}
线程池的大小是有界的,即线程个数可以控制,但是,等待队列是无界的,等待队列没有容量限制,任务就有可能堆积,一直把内存占满,发生OOM。
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);
}线程池中线程的数目是不受限制的,如果业务运行时间比较长,一直不释放持有的线程,导致线程数目暴增,会发生OOM。
java.util.concurrent.Executors#newSingleThreadExecutor(...) 解析
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}线程池中线程数目为1,但是等待队列也是无容量限制的。
总结
线程池不允许使用 Executors 去创建,因为创建的线程池很容易导致OOM的发生,我们还是显示的通过ThreadPoolExecutor创建,合理设置7大参数。
jdk源码版本:
java version "17.0.2" 2022-01-18 LTS
Java(TM) SE Runtime Environment (build 17.0.2+8-LTS-86)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.2+8-LTS-86, mixed mode, sharing)