除非队列已满,否则在固定大小的线程池中同时运行线程的计数是否总是小于corePoolSize?

时间:2016-02-24 12:53:07

标签: java threadpoolexecutor

javadoc说:

  

提交新任务[...]时,少于corePoolSize   线程正在运行,创建一个新线程来处理请求,   即使其他工作线程处于空闲状态。如果有更多   corePoolSize但运行的maximumPoolSize线程少于一个新的   只有在队列已满时才会创建线程。通过设置   corePoolSize和maximumPoolSize相同,你创建一个固定大小   线程池。通过将maximumPoolSize设置为基本无界限   如Integer.MAX_VALUE这样的值,允许池容纳一个   任意数量的并发任务。

这是否意味着固定大小的线程池中同时运行的线程的计数总是小于corePoolSize,除非队列已满?

1 个答案:

答案 0 :(得分:1)

  

这是否意味着在固定大小的线程池中同时运行的线程的计数总是小于corePoolSize,除非队列已满?

不,它没有。

语义方法

在我阅读它和用于固定大小的池时,这个引用没有说明与队列大小有关的活动线程数。绑这两个的唯一一句就是这个:

  

如果有超过corePoolSize但运行的maximumPoolSize线程少于,则只有在队列已满时才会创建新线程。

哪个不适用,因为在固定大小的池中,corePoolSize等于maximumPoolSize。 “if”条件永远不会得到满足。

它所说的是:

  

当提交新任务[...]并且运行的线程少于corePoolSize时,即使其他工作线程处于空闲状态,也会创建一个新线程来处理该请求。

只要未达到corePoolSize限制,就会创建线程。只要未达到此限制,线程就不会被重用(但是可能死亡,未捕获的异常,或者通过池的超时功能)。如果我们创建足够快的队列或者有足够长的队列,这显然为创建corePoolSize个线程留下了空间。

实验方法

这些知识让我们可以想象这个场景:创建一个大小为2的固定池,其中一个大小为5的等待队列,然后将两个长时间运行的任务提交给池。 (“长时间运行”意味着每个任务的执行时间比主线程提交它们所花费的时间大一个数量级,并且线程池要确认它们的存在并对它们进行处理)。可能的计划如下:

  1. 主线程将任务T1提交给新的空池
  2. 根据上述引用,corePoolSize尚未被命中,将创建一个新线程来执行T1。
  3. 线程1开始执行T1
  4. 主线程提交T2
  5. 与步骤2中一样,生成第二个线程,池到达corePoolSize
  6. 与步骤3中一样,第二个线程开始执行任务T2
  7. 此时,线程池具有空队列,并且正在运行的线程数完全为corePoolSize,而不是“在corePoolSize下”,QED。

    它的意思是:

    另一种方式,这意味着,获得大于corePoolSize的线程数的唯一方法是同时满足所有条件:

    1. 大量(或等于)corePoolSize
    2. 的运行线程数
    3. maximumPoolSize大于corePoolSize
    4. 一个完整的队列