corePoolSize
为零。
开发人员有时会将核心大小设置为零,以便工作线程最终被销毁,从而不会阻止JVM退出,但这可能会导致一些在其工作队列中不使用SynchronousQueue(如newCachedThreadPool)的线程池产生奇怪的行为。 如果线程池已经达到核心大小,则ThreadPoolExecutor仅在工作队列已满时创建新线程。 因此,对于具有任何容量和核心大小为零的工作队列的线程池提交的任务将不执行,直到队列填满,这通常不是所期望的。
因此,为了验证这一点,我编写了以下程序,它并不按照上述方式工作。
final int corePoolSize = 0;
ThreadPoolExecutor tp = new ThreadPoolExecutor(corePoolSize, 1, 5, TimeUnit.SECONDS,
new LinkedBlockingQueue<>());
// If the pool is already at the core size
if (tp.getPoolSize() == corePoolSize) {
ExecutorService ex = tp;
// So tasks submitted to a thread pool with a work queue that has any capacity
// and a core size of zero will not execute until the queue fills up.
// So, this should not execute until queue fills up.
ex.execute(() -> System.out.println("Hello"));
}
输出: Hello
因此,该程序的行为是否表明ThreadPoolExecutor
在提交任务时创建至少一个线程,而不考虑corePoolSize=0
。 如果是,则文本书中的警告是什么。
编辑:根据@S.K.的建议,在jdk1.5.0_22中测试了以下更改的代码:
ThreadPoolExecutor tp = new ThreadPoolExecutor(corePoolSize, 1, 5, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(1));//Queue size is set to 1.
但是随着这个更改,程序无法打印任何输出而终止。
所以我对书中的这些陈述有误解吗?
编辑(@sjlee):在评论中添加代码很困难,因此我将其作为编辑添加在此处...您可以尝试进行此修改,并针对最新的JDK和JDK 1.5运行它。
final int corePoolSize = 0;
ThreadPoolExecutor tp = new ThreadPoolExecutor(corePoolSize, 1, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
// If the pool is already at the core size
if (tp.getPoolSize() == corePoolSize) {
ExecutorService ex = tp;
// So tasks submitted to a thread pool with a work queue that has any capacity
// and a core size of zero will not execute until the queue fills up.
// So, this should not execute until queue fills up.
ex.execute(() -> System.out.println("Hello"));
}
tp.shutdown();
if (tp.awaitTermination(1, TimeUnit.SECONDS)) {
System.out.println("thread pool shut down. exiting.");
} else {
System.out.println("shutdown timed out. exiting.");
}
@sjlee已在评论中发布了结果。
thread pool shut down. exiting.
,JDK 1.8 的输出是Hello thread pool shut down. exiting.
。 - StevecorePoolSize
=0,任务也不会执行。我无法理解这一点。 - SteveallowCoreThreadTimeOut允许您请求所有池线程都能够超时;如果您想要一个有界线程池和有界工作队列,但仍然希望在没有工作可做时关闭所有线程,请使用零个核心大小启用此功能。
"使用零个核心大小启用此功能"没有意义。 - Jason