java - 使用多个执行程序时,理想/最佳线程池大小是多少?

标签 java multithreading concurrency

从许多帖子中我可以读到有关最大池大小的公式,它取决于 CPU 的数量 + 1。这是一个明确的解释。

但是如果应用程序定义了许多执行器或线程池执行器怎么办。然后我们还必须考虑应用程序共享相同的硬件。这对池大小的选择有何影响。

我们是否需要根据定义的线程池的数量全局计算大小和划分?

最佳答案

nosCPUs + 1“经验法则”假定线程将受 CPU 限制(而非 I/O 限制)并且不会出现明显的锁争用。这对于典型应用来说是不现实的。

如果你有多个线程池,你还得考虑各个池中的线程是否会同时忙碌。

  • 如果它们是并且之前的假设对所有池都为真,则可以全局应用 nosCPUs + 1 规则;即所有池的大小之和。

  • 否则,计算出预测池的最佳大小的公式很可能过于复杂。


在实践中,典型多线程应用程序的行为非常复杂,以至于 nosCPUs + 1 规则无法给出最佳线程数。此外,您通常无法推导出允许您准确预测最佳线程数的公式。

相反,通常的做法是将您的线程池大小设置为可调参数或属性,并调整它们以获得典型工作负载的良好性能。如果您的应用程序只有一个线程池,这将使调整更容易,尽管可能有理由不这样做。

但好消息是,有点太大的有界线程池对性能的影响通常并不显着。当池大小太大时,就会出现问题(内存使用、争用、上下文切换等)。


最后,我认为您应该重新审视让许多执行程序都有自己的线程池的决定。由于多个池中(长期)空闲线程的线程堆栈,这很容易导致内存浪费。此外,如果您有许多池要单独调整,则调整池大小的任务将更加困难。相反,如果您对所有池都有一个“调整旋钮”,您最终会针对所有池的最坏情况调整池大小。

您需要权衡这些问题/成本与拥有多个执行程序对您的应用程序的好处。 (我可以看到在某些用例中会有好处......)

关于java - 使用多个执行程序时,理想/最佳线程池大小是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47845759/

相关文章:

java - BigQueryIO.writeTableRows() 中的 GroupByKey 节点不发出元素

java - 如何通过 start-stop-daemon 优雅地关闭 Spring Boot 应用程序

c# - 使用时间戳跟踪并发 Web 服务请求

java - 并发使用 java.util.Random 的争用

c++ - 为什么不在 pop 之后运行任务并返回 true?

java - 调整 HashMap 存储桶的大小

java - 如何使用 Swing 创建方法,使用计时器 sleep

java - JPA:查询子项时未反射(reflect)父项更改

java - spring 集成 channel 是单线程的吗?

c# - 使用 C# 的线程池问题