Spring ThreadPoolTask​​Executor中的corePoolSize和maxPoolSize有什么区别

rab*_*bit 35 java spring multithreading

我必须向网站的所有用户发送massEmails.我想为发出的每封电子邮件使用一个线程池.目前我已将值设置为:

<property name="corePoolSize" value="500" />
<property name="maxPoolSize" value="1000" />
Run Code Online (Sandbox Code Playgroud)

两者之间有什么区别,它会扩展吗?目前我有约.10000个用户.

ska*_*man 40

javadoc说得最好:

当提交新任务[...]并且corePoolSize运行的线程少于线程时,即使其他工作线程处于空闲状态,也会创建一个新线程来处理请求.如果运行的线程数多于corePoolSize但少于 maximumPoolSize线程,则仅当队列已满时才会创建新线程.通过设置 corePoolSizemaximumPoolSize 相同,您可以创建固定大小的线程池.通过设置 maximumPoolSize基本上无限制的值,例如 Integer.MAX_VALUE,允许池容纳任意数量的并发任务.

至于你的具体情况,同时发送500封电子邮件是没有意义的,你只会压倒邮件服务器.如果您需要发送大量电子邮件,请使用单个线程,然后一次将其发送到管道中.邮件服务器将比500个单独的连接更优雅地处理这个问题.


tay*_*yen 26

以下是Sun用简单术语创建线程的规则:

  1. 如果线程数小于corePoolSize,则创建一个新线程来运行新任务.
  2. 如果线程数等于(或大于)corePoolSize,则将任务放入队列.
  3. 如果队列已满,并且线程数小于maxPoolSize,则创建一个新线程来运行任务.
  4. 如果队列已满,并且线程数大于或等于maxPoolSize,则拒绝该任务.

全文

来源答案


Thi*_*ilo 19

corePoolSize是池使用的最小线程数.这个数字可以增加到maxPoolSize.当负载下降时,池将缩小回去corePoolSize.

发送电子邮件似乎是一个I/O绑定操作.我不认为拥有500个线程会让它更快.


Kum*_*osh 12

我们已经有很多答案了,就足够了,但我总是每隔一天就感到困惑。所以我想出了一个实时的例子来说明这一点!

实现这一点的一个简单而有效的方法是想象自己在银行。

您是否曾经在有窗口的情况下排队?如果有可用的现金窗口,银行为什么要让客户排队呢?情况正是如此core pool size。如果有未使用的线程,则直接分配新任务给它们。

在此输入图像描述

一可用窗口(核心池大小)已满,客户被要求排队等候。这就是图中出现的地方queue-capacity!新任务将继续排队,直到没有更多任务可以排队为止。

在此输入图像描述

如果候诊室里挤满了顾客怎么办?当银行看到客户(任务)数量激增时,可以分配/开设新的现金窗口。他们还有3个备用。这是max pool size上下文。

一旦这些窗口(线程)全部被占用,银行就无法再为任何新客户(任务)提供服务。同意?从此以后不再接受新任务!

在此输入图像描述


Mah*_*aha 5

除了 @skaffman 从官方文档中指出的内容之外,以下内容也更清楚地说明了如何利用这些尺寸:

AnyBlockingQueue可用于传输和保存已提交的任务。该队列的使用与池大小相互作用:

  • corePoolSize如果运行的线程少于几个,则Executor总是倾向于添加新线程而不是排队。
  • 如果有corePoolSize一个或多个线程正在运行,则Executor总是倾向于对请求进行排队而不是添加新线程。
  • 如果请求无法排队,则会创建一个新线程,除非超出maximumPoolSize,在这种情况下,任务将被拒绝。