线程池大小应远远超过核心数+ 1

时间:2015-12-14 23:02:27

标签: java multithreading tomcat threadpool

自定义线程池的建议大小为number_of_cores + 1(请参阅herehere)。因此,假设在具有2个内核的系统上有一个Spring应用程序,配置就像这样

<task:executor id="taskExecutor" 
pool-size="#{T(java.lang.Runtime).getRuntime().availableProcessors() + 1}" />
<task:annotation-driven executor="taskExecutor" />

在这种情况下,将在多个请求之间共享一个ExecutorService。因此,如果10个请求到达服务器, 在ExecutorService中只能同时执行其中的3个。这可能会产生瓶颈,并且在请求数量较多的情况下结果会变得更糟(请记住:默认情况下,tomcat最多可以处理200个并发请求= 200个线程)。该应用程序将执行得更好,没有任何池。

通常一个核心可以同时处理多个线程。 例如我创建了一个服务,它调用两次https://httpbin.org/delay/2。每次调用都需要2秒才能执行。因此,如果没有使用线程池,则服务平均响应4.5秒(使用20个同时请求进行测试)。 如果使用线程池,则响应因池大小和硬件而异。我在具有不同池大小的4核心机器上运行测试。以下是最小,最大和平均响应时间(以毫秒为单位)的测试结果

min, max and average response times in milliseconds

从结果可以得出结论,最佳平均时间是最大池大小。池中5(4个核心+ 1)线程的平均时间比没有池的结果更糟糕。因此,在我看来,如果请求不占用大量CPU时间,那么将线程池限制为Web应用程序中的核心数+ 1是没有意义的。

对于非CPU要求的Web服务,是否有人发现在2或4核心机器上将池大小设置为20(甚至更多)有什么问题?

1 个答案:

答案 0 :(得分:5)

您链接到的两个页面都明确表示这仅适用于未阻止的CPU绑定任务。

您有在远程计算机上等待阻止的任务,因此该建议不适用。

忽略不适用于您的建议没有任何问题,因此您可以而且应该增加线程池大小。

  

良好的建议伴随着理由,所以你可以告诉它什么时候成为糟糕的建议。如果你不理解为什么要做某事,那么你就陷入了货物崇拜编程的陷阱,即使它不再需要甚至变得有害,你也会继续这样做。

Raymond Chen,在他的博客“The Old New Thing”