我一直在阅读 Spring 的 ThreadPoolTaskExecutor 的设置如何协同工作以及线程池和队列如何工作。This https://stackoverflow.com/a/43874563/10727434stackoverflow 的答案以及this https://www.baeldung.com/thread-pool-java-and-guava and this https://www.baeldung.com/java-threadpooltaskexecutor-core-vs-max-poolsizeBaeldung 的文章对我很有用。
据我所知,到目前为止,corePoolSize 线程数始终保持活动状态(假设allowCoreThreadTimeOut 未设置为true)。如果所有这些线程当前都在使用中,则任何其他请求都将放入队列中。一旦达到queueCapacity,线程池大小将增加,直到达到maxPoolSize。
直觉上,我本以为它会按如下方式工作:
corePoolSize 线程数量始终保持活动状态(再次假设 allowedCoreThreadTimeOut 未设置为 true)。如果所有这些线程当前都在使用并且有新请求进来,则池大小将增加,直到达到 maxPoolSize。如果还有更多请求进来,它们将被放入队列中,直到达到queueCapacity。
我想知道它以这种方式工作背后的原因是什么?
您应该检查的第一个参考是文档。
直接从文档中ThreadPoolExecutor https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/ThreadPoolExecutor.html (ThreadPoolTaskExecutor
“只是”一个包装器):
ThreadPoolExecutor 将根据 corePoolSize(请参阅 getCorePoolSize())和 maxPoolSize(请参阅 getMaximumPoolSize())设置的边界自动调整池大小(请参阅 getPoolSize())。当在方法execute(Runnable)中提交新任务时,如果运行的线程少于corePoolSize,则会创建一个新线程来处理该请求,即使其他工作线程处于空闲状态。否则,如果正在运行的线程少于 maxPoolSize,则仅当队列已满时才会创建一个新线程来处理请求。 [...]
如果池当前拥有超过 corePoolSize 的线程,则多余的线程如果空闲时间超过 keepAliveTime(请参阅 getKeepAliveTime(TimeUnit)),将被终止。这提供了一种在池未被积极使用时减少资源消耗的方法。如果池稍后变得更加活跃,则会构造新线程。 [...]
(你还没有提到的参数BlockingQueue
但我建议您也阅读一下。这很有趣。)
为什么这些参数不能像您建议的那样工作?
如果池大小增加到maximumPoolSize
在任务排队之前(就像您建议的那样),您会遇到一个问题:您已经删除了线程池确定的能力when一个新工人是值得的。
The corePoolSize
是工人的数量stay在游泳池。好处是您不必为给定的工作负载创建、终止、创建、终止、创建……新工作线程。如果你能确定有多少工作量always是,设置corePoolSize
因此。
The maximumPoolSize
确定池中工人的最大数量。您希望对此进行控制,因为您可以拥有多个线程池、硬件限制或只是一个不需要那么多工作人员的特定程序。
现在为什么工作队列首先被填满?因为队列容量是一个指标when工作量如此之大,以至于值得去创造新的工人。只要队列未满,核心工作人员就应该足以处理给定的工作。如果达到容量,则会创建新的工作人员来处理进一步的工作。
通过这种机制,线程池动态创建工人when需要他们,而且只能保留尽可能多的工人usually需要。这就是线程池的要点。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)