我必须向网站的所有用户发送massEmails。我想为发出的每封电子邮件使用一个线程池。目前我已将值设置为:
<property name="corePoolSize" value="500" />
<property name="maxPoolSize" value="1000" />
两者之间有什么区别,它会扩展吗?目前我有约。 10000名用户。
答案 0 :(得分:37)
当一个新的 任务提交[...],和 少于
corePoolSize
个线程 正在运行,创建一个新线程 处理请求,即使其他 工作线程闲置。如果有 超过corePoolSize
但小于maximumPoolSize
运行corePoolSize
个线程,a 只有在创建新线程时才会创建 队列已满。通过设置maximumPoolSize
和maximumPoolSize
同样,你创建一个固定大小 线程池。通过设置 基本上Integer.MAX_VALUE
无限的价值,如 {{1}},你允许 游泳池容纳任意 并发任务数。
至于你的具体情况,同时发送500封电子邮件毫无意义,你只会压倒邮件服务器。如果您需要发送大量电子邮件,请使用单个线程,然后一次将其发送到管道中。邮件服务器将比500个单独的连接更优雅地处理这个问题。
答案 1 :(得分:20)
以下是Sun用简单术语创建线程的规则:
corePoolSize
,请创建一个新线程以运行新任务。corePoolSize
,则将任务放入队列。maxPoolSize
,请创建一个新线程以运行任务。maxPoolSize
,请拒绝该任务。答案 2 :(得分:19)
corePoolSize
是池使用的最小线程数。该数字最多可增加maxPoolSize
。当负载下降时,池将缩小回corePoolSize
。
发送电子邮件似乎是一个I / O绑定操作。我不认为拥有500个线程会让它更快。
答案 3 :(得分:4)
您应该考虑增加 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"/>
如果您有10000个用户要发送1000 * 10(maxPoolSize)= 10000但是如果每个线程的1000很重,我们可以考虑增加poolSize。
答案 4 :(得分:2)
除了@skaffman从official docs所指出的内容之外,以下内容还使我们更加清楚了如何利用这些大小:
任何BlockingQueue
均可用于传输和保留提交的任务。此队列的使用与池大小交互:
corePoolSize
,则Executor
总是更喜欢添加新线程而不是排队。corePoolSize
个或更多线程,则Executor
总是更喜欢对请求进行排队,而不是添加新线程。maximumPoolSize
,在这种情况下,该任务将被拒绝。答案 5 :(得分:0)
每个人都这么清楚地解释了什么是正确的。这里要注意的几件事是,核心池和队列的大小始终应该有限。如果core-pool-size很高,则很有可能您的池中的许多线程在一段时间内保持未使用状态,因为对于每个请求,都会创建新线程,直到达到max-pool-size
但是,如果您的计算机要同时面对大量请求,那么您还应该考虑计算机大小是否足够:示例:
如果您的计算机大小为1 GB,并且队列容量为Integer.MAX_VALUE,则由于可以在任何JVM GUI工具中监视的OutOfMemory,您的计算机很有可能在某个时间点开始拒绝请求。