Java Spring ThreadPoolTaskExecutor中corePoolSize和maxPoolSize有什么区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1878806/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the difference between corePoolSize and maxPoolSize in the Spring ThreadPoolTaskExecutor
提问by rabbit
I have to send out massEmails to all users of a website. I want to use a thread pool for each email that is sent out. Currently I have set the values to :
我必须向网站的所有用户发送大量电子邮件。我想为发送的每封电子邮件使用一个线程池。目前我已将值设置为:
<property name="corePoolSize" value="500" />
<property name="maxPoolSize" value="1000" />
What is the difference between the two and will it scale. Currently I have approx. 10000 users.
两者有什么区别,是否会扩展。目前我有大约。10000 个用户。
回答by Thilo
corePoolSize
is the minimum number of threads used by the pool. The number can increase up to maxPoolSize
. When the load goes down, the pool will shrink back to corePoolSize
.
corePoolSize
是池使用的最小线程数。数量最多可以增加到maxPoolSize
。当负载下降时,池将收缩回corePoolSize
。
Sending email seems to be an I/O bound operation. I do not think having 500 threads will make it faster.
发送电子邮件似乎是一个 I/O 绑定操作。我认为拥有 500 个线程不会使它更快。
回答by skaffman
When a new task is submitted [...], and fewer than
corePoolSize
threads are running, a new thread is created to handle the request, even if other worker threads are idle. If there are more thancorePoolSize
but less thanmaximumPoolSize
threads running, a new thread will be created only if the queue is full. By settingcorePoolSize
andmaximumPoolSize
the same, you create a fixed-size thread pool. By settingmaximumPoolSize
to an essentially unbounded value such asInteger.MAX_VALUE
, you allow the pool to accommodate an arbitrary number of concurrent tasks.
当提交一个新任务 [...] 并且
corePoolSize
运行的线程数少于一个时,即使其他工作线程空闲,也会创建一个新线程来处理请求。如果运行的线程多于corePoolSize
但少于maximumPoolSize
线程,则只有在队列已满时才会创建新线程。通过设置corePoolSize
和maximumPoolSize
相同,你创建了一个固定大小的线程池。通过设置maximumPoolSize
为一个基本上无限的值,例如Integer.MAX_VALUE
,您可以允许池容纳任意数量的并发任务。
As for your specific situation, sending 500 emails all at the same time is pointless, you'll just overwhelm the mail server. If you need to send a large number of emails, then use a single thread, and send them down the pipe one at a time. The mail server will handle this much more gracefully than 500 separate connections.
至于您的具体情况,同时发送 500 封电子邮件是没有意义的,您只会使邮件服务器不堪重负。如果您需要发送大量电子邮件,请使用单个线程,并一次发送一个。邮件服务器将比 500 个单独的连接更优雅地处理这个问题。
回答by Osify
You should consider to increase value of queueCapacitythan consider to increase value of corePoolSizeor maxPoolSize. Those two properties (*PoolSize) are number of pool to execute but each message would be considering in queueCapacity
您应该考虑增加queueCapacity 的值而不是考虑增加corePoolSize或maxPoolSize 的值。这两个属性 (*PoolSize) 是要执行的池数,但每条消息都将在queueCapacity 中考虑
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="queueCapacity" value="1000" />
<property name="waitForTasksToCompleteOnShutdown" value="true"/>
If you have 10000 users to send so 1000 * 10 (maxPoolSize) = 10000 but if 1000 for each thread is heavy, we can consider to increase poolSize.
如果你有 10000 个用户发送所以 1000 * 10 (maxPoolSize) = 10000 但如果每个线程 1000 很重,我们可以考虑增加 poolSize。
回答by taynguyen
Here are Sun's rules for thread creation in simple terms:
以下是 Sun 的线程创建规则,简单来说:
- If the number of threads is less than the
corePoolSize
, create a new Thread to run a new task. - If the number of threads is equal (or greater than) the
corePoolSize
, put the task into the queue. - If the queue is full, and the number of threads is less than the
maxPoolSize
, create a new thread to run tasks in. - If the queue is full, and the number of threads is greater than or equal to
maxPoolSize
, reject the task.
- 如果线程数小于
corePoolSize
,则创建一个新线程来运行新任务。 - 如果线程数等于(或大于)
corePoolSize
,则将任务放入队列中。 - 如果队列已满,并且线程数小于
maxPoolSize
,则创建一个新线程来运行任务。 - 如果队列已满,并且线程数大于或等于
maxPoolSize
,则拒绝该任务。
回答by SinhaOjas
What everyone has explained so clearly is correct. Few things to notice here is that you should always have a limited size for core-pool as well as queue. If the core-pool-size if very high, there can a high chance that many of your threads from pool are remaining unused for certain period of time since for every request new thread gets created until it reaches max-pool-size
大家解释的这么清楚是对的。这里需要注意的几件事是,您应该始终为核心池和队列设置有限的大小。如果 core-pool-size 非常高,则池中的许多线程很可能在一段时间内未使用,因为每次请求都会创建新线程,直到达到 max-pool-size
But if your machine is going to face large number of request concurrently then you should also consider that the machine size is sufficient enough : example:
但是如果您的机器将同时面临大量请求,那么您还应该考虑机器大小是否足够:例如:
If your machine size in 1 GB and queue capacity is at Integer.MAX_VALUE then there is a high chance that your machine will start rejecting the requesting at some point of time because of OutOfMemory which you can monitor in any JVM GUI tool.
如果您的机器大小为 1 GB,队列容量为 Integer.MAX_VALUE,那么您的机器很可能会在某个时间点开始拒绝请求,因为您可以在任何 JVM GUI 工具中监控 OutOfMemory。
回答by Mahesha999
In addition to what @skaffman pointed out from official docs, following also makes it more clear how these sizes are utilized:
除了@skaffman 从官方文档中指出的内容之外,以下内容也更清楚地说明了如何使用这些尺寸:
Any BlockingQueue
may be used to transfer and hold submitted tasks. The use of this queue interacts with pool sizing:
AnyBlockingQueue
可用于传输和保留提交的任务。此队列的使用与池大小交互:
- If fewer than
corePoolSize
threads are running, theExecutor
always prefers adding a new thread rather than queuing. - If
corePoolSize
or more threads are running, theExecutor
always prefers queuing a request rather than adding a new thread. - If a request cannot be queued, a new thread is created unless this would exceed
maximumPoolSize
, in which case, the task will be rejected.
- 如果少于
corePoolSize
线程正在运行,则Executor
总是更喜欢添加新线程而不是排队。 - 如果一个
corePoolSize
或多个线程正在运行,则Executor
总是更喜欢将请求排队而不是添加新线程。 - 如果请求无法排队,则会创建一个新线程,除非超过
maximumPoolSize
,在这种情况下,任务将被拒绝。