Java中一个线程池的核心线程为什么不能在初始阶段复用?

Jac*_*_Du 5 java multithreading

最近看ThreadPoolExecutor的源码有个疑问:如果线程池代表重用已有线程来减少线程创建或销毁的开销,那为什么不在初始阶段重用核心线程呢?即当当前线程数小于核心线程数时,首先检查是否有核心线程完成了任务,如果有,重用。为什么不?而不是在达到核心线程数之前创建新线程,这是否违反了线程池设计原则?

下面是对ThreadPoolExecutor中addWorker()方法的部分注释

  • @param firstTask 新线程应该首先运行的任务(如果没有,则为 null)。当线程少于 corePoolSize 时(在这种情况下我们总是启动一个),或者当队列已满(在这种情况下我们必须绕过队列)时,使用初始的第一个任务(在方法 execute() 中)创建工人. 最初空闲线程通常通过 prestartCoreThread 创建或替换其他垂死的工人。

aku*_*ykh 4

实际上已经请求了:JDK-6452337。核心库开发人员指出:

\n
\n

我喜欢这个想法,但是 ThreadPoolExecutor 已经足够复杂了。

\n
\n

请记住,这corePoolSize是 的重要组成部分ThreadPoolExecutor,并且表示至少有多少工作人员始终处于活动/闲置状态。达到这个数字自然需要很短的时间。您根据需要设置corePoolSize,预计工作负载将满足这个数字。

\n

我的假设是,优化这个“预热阶段”\xe2\x80\x93 理所当然地认为这实际上提高效率 \xe2\x80\x93 是不值得的。我无法为您量化这种优化会带来多少额外的复杂性,我不是在开发 Java Core 库,但我认为这不值得。

\n

您可以这样想:“预热阶段”是恒定的,而线程池将运行不确定的时间。在理想的情况下,初始阶段实际上根本不应该花费任何时间,工作负载应该在您创建线程池时就存在。因此,您正在考虑一种优化,以优化非预期线程池状态的内容。

\n

无论如何,线程工作者必须在某个时候被创建。这种优化只会延迟创建。假设您的 acorePoolSize为 10,那么至少有创建 10 个线程的开销。如果您稍后执行此操作,此开销不会改变。是的,稍后也会占用资源,但这里我首先要问的是线程池是否配置正确:是否corePoolSize正确,是否满足当前工作负载?

\n

请注意,它具有类似和等ThreadPoolExecutor方法,允许您根据需要配置线程池。setCorePoolSize(int)allowCoreThreadTimeOut(boolean)

\n