Java Spring ThreadPoolTaskExecutor中的corePoolSize和maxPoolSize之间有什么区别

Java Spring ThreadPoolTaskExecutor中的corePoolSize和maxPoolSize之间有什么区别,java,spring,multithreading,Java,Spring,Multithreading,我必须向网站的所有用户发送大量电子邮件。我想为发送的每封电子邮件使用一个线程池。目前,我已将值设置为: <property name="corePoolSize" value="500" /> <property name="maxPoolSize" value="1000" /> 两者之间的区别是什么?它会扩展吗。目前我有大约10000个用户。corePoolSize是池使用的最小线程数。该数字最多可增加到maxPoolSize。当负载下降时,池将收缩回coreP

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

<property name="corePoolSize" value="500" />
<property name="maxPoolSize" value="1000" />


两者之间的区别是什么?它会扩展吗。目前我有大约10000个用户。

corePoolSize
是池使用的最小线程数。该数字最多可增加到
maxPoolSize
。当负载下降时,池将收缩回
corePoolSize

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

:

当一个新的 任务已提交[…],并且 少于
corePoolSize
的线程 运行时,将创建一个新线程以 处理请求,即使其他 工作线程处于空闲状态。如果有 大于
corePoolSize
但小于
maximumPoolSize
正在运行的线程,a 仅当 队列已满。通过设置
corePoolSize
maximumPoolSize
同样,您可以创建一个固定的大小 线程池。通过设置
maximumPoolSize
无界值,例如
整数。最大值
,您允许 可容纳任意 并发任务的数量


至于你的具体情况,同时发送500封电子邮件是毫无意义的,你只会压倒邮件服务器。如果你需要发送大量的电子邮件,那么使用一个线程,然后一次一个地发送。邮件服务器将比500个单独的连接处理得更优雅。

应考虑增加<强> QuealEppActudio的值,而不是考虑增加<强> CopePoLosie< <强> >或<强> MyPooListSuth/St>>。这两个属性(*PoolSize)是要执行的池数,但每个消息都将在队列容量中考虑



如果你有10000个用户发送这样的1000×10(MyPoLosiScript)=10000,但是如果每个线程的1000都是重的,我们可以考虑增加POLLASSIZE。

< P>这里简单地说:Sun的线程创建规则:

  • 如果线程数小于
    corePoolSize
    ,请创建新线程以运行新任务
  • 如果线程数等于(或大于)corePoolSize,则将任务放入队列
  • 如果队列已满,且线程数小于
    maxPoolSize
    ,请创建一个新线程以在其中运行任务
  • 如果队列已满,且线程数大于或等于
    maxPoolSize
    ,则拒绝该任务

  • 大家解释得如此清楚是正确的。这里需要注意的几件事是,您应该始终为核心池和队列设置一个有限的大小。如果核心池大小非常大,则池中的许多线程很可能在一定时间内未使用,因为对于每个请求,都会创建新线程,直到达到最大池大小

    <>但是如果你的机器同时面临大量的请求,那么你也应该考虑机器的大小足够了:例如:


    如果您的机器大小为1 GB,队列容量为Integer.MAX_值,那么您的机器很有可能在某个时间点开始拒绝请求,因为您可以在任何JVM GUI工具中监视OutOfMemory。

    除了@skaffman指出的,以下内容也更清楚地说明了如何利用这些尺寸:

    任何
    BlockingQueue
    都可用于传输和保存提交的任务。此队列的使用与池大小交互:

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

    我认为您的意思是“每封电子邮件有一个线程”,而不是“每封电子邮件有一个线程池”,队列容量默认为Integer.MAX_值,因此无需增加它@rlm,在这种情况下,将不再创建线程,线程将保持在
    corePoolSize
    @rlm。这与@taynguyen的答案相矛盾?根据这个答案,只有当队列已满时,才会创建新线程。@BillMan,taynguyen的答案是sun实现,但提出这个问题的开发人员谈论的是“Spring ThreadPoolTaskExecutor”。在“Spring ThreadPoolTaskExecutor”中,队列容量也初始化为整数最大值和最大池大小,以便“允许池容纳任意数量的并发任务(skaffman)”@rlm:默认配置为核心池大小1,最大池大小和队列容量不限。这大致相当于Executors.newSingleThreadExecutor(),那么,您能在这个
    ThreadExecutor
    中解释一下这种奇怪的行为吗。它没有遵循您在这里提到的4种情况。我无法在这个
    ThreadExecutor
    中看到这种情况发生。你能解释一下这里有什么不同吗?
    <property name="corePoolSize" value="5" />
    <property name="maxPoolSize" value="10" />
    <property name="queueCapacity" value="1000" />
    <property name="waitForTasksToCompleteOnShutdown" value="true"/>