【发布时间】:2019-02-14 14:45:44
【问题描述】:
我正在阅读 Java Concurrency In Practice 并被困在 8.3.1 线程创建和拆卸 主题上。以下脚注警告将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"));
}
输出: 你好
那么,程序的行为是否表明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 已将结果发布到 cmets。
【问题讨论】:
-
@sjlee jdk 1.5 的输出是
thread pool shut down. exiting.,jdk 1.8 的输出是Hello thread pool shut down. exiting. -
好的,谢谢。正如您在下面发现的那样,JDK 在这方面似乎将行为从 1.5 略微更改为 1.6。
-
@sjlee 但是任何java版本中的代码都不会推断教科书中提到的文本。我是否错误地解释了文本?根据我在问题中的示例,即使任务队列已满
corePoolSize=0,任务也不会执行。我无法理解那一点。 -
本例中的“教科书”是Java Concurrency in Practice?除非不断更新,否则技术书籍一直都过时了。我只是认为这在出版时是正确的,但现在已经不是这样了。更重要的是javadoc(API doc)。我相信当核心池大小 = 0 时,API 文档非常模糊,所以这并不是合同的真正中断。至于任务队列已满且核心池大小 = 0,您能否发布一个代码示例来说明这一点?
-
@sjlee 我已经在我的问题中做了。看jdk1.5的测试结果。这里,核心池大小=0,任务队列大小=1,提交的任务数量=1。
标签: java multithreading concurrency threadpool java-threads