ThreadPoolTask​​Executor的Spring的默认队列大小是什么?

时间:2017-06-19 19:02:57

标签: spring multithreading queue threadpool threadpoolexecutor

我使用Spring 4.3.8.RELEASE和Java 7.我想创建一个线程池来执行任务,所以我在Spring consxet中设置了以下内容

<bean id="myThreadFactory" class="org.springframework.scheduling.concurrent.CustomizableThreadFactory">
    <constructor-arg value="mythread-"/>
</bean>
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="threadFactory" ref="myThreadFactory"/>
    <property name="corePoolSize" value="10" />
    <property name="maxPoolSize" value="50" />
</bean>

为了不破坏机器的CPU使用率,我想限制系统中可能存在的并发线程数量(我假设这是maxPOolSize的作用)。但我不想让任务掉线。如果我向taskPoolExecutor添加了50多个任务,51号会发生什么?更重要的是,在开始被删除之前可以添加的默认任务数是多少?

2 个答案:

答案 0 :(得分:9)

设置maxPoolSize隐式允许删除任务。 但是,默认队列容量为Integer.MAX_VALUE,出于实际目的,该容量为无穷大。

值得注意的是ThreadPoolTaskExecutor下面使用ThreadPoolExecutor,这有一种不同寻常的排队方法,在the docs中有描述:

  

如果corePoolSize个或更多线程正在运行,则执行程序总是更喜欢排队请求而不是添加新线程。

这意味着maxPoolSize仅在队列已满时才相关,否则线程数将永远不会超过corePoolSize。 例如,如果我们向线程池提交永远不会完成的任务:

  • 第一个corePoolSize提交将分别开始一个新主题;
  • 之后,所有提交都进入队列;
  • 如果队列是有限的并且其容量已用尽,则每次提交都会启动一个新线程,最多为maxPoolSize;
  • 当池和队列都已满时,新的提交将被拒绝。

答案 1 :(得分:0)

如果执行许多ThreadPoolTaskExecutor任务,请注意使用默认的@Async

从Spring Boot 2.1开始,有一个默认的ThreadPoolTaskExecutor,其默认核心大小为8个线程。尽管最大池大小仍为无穷大¹,并且理论上可以创建新线程,但该池的队列大小也为无穷大¹。

队列大小可能永远不会达到,并且永远不会创建新线程。

如果使用@Async,请至少设置队列大小:

spring.task.execution.pool.queue-capacity=16

¹无穷大,例如2147483647 a.k.a. Integer.MAX_VALUE