我正在编写一个使用大量CPU的Java程序,因为它的功能本质.但是,很多都可以并行运行,而且我的程序是多线程的.当我运行它时,它似乎只使用一个CPU,直到它需要更多然后它使用另一个CPU - 我有什么可以用Java来强制不同的线程在不同的核心/ CPU上运行吗?
我打算制作一个像网络连接一样的对等软件.通常我会为每个连接创建一个自己的线程来发送和接收数据,但在这种情况下,有300-500 +连接,这意味着不断创建和销毁很多线程,这将是一个很大的开销我猜.并且制作一个顺序处理所有连接的线程可能会减慢一些事情.(我对此不太确定.)
问题是:有多少线程可以处理这类问题?是否有可能在软件中进行计算,以便它可以决定在旧计算机上创建更少的线程,而没有更多的资源和更多的新资源?
这是一个理论问题,我不想让它实现或依赖于语言.但是我认为很多人都会建议像"只使用一个ThreadPool,它会处理类似的东西"所以让我们说它不会是一个.NET应用程序.(我可能不得不在旧的Delphi项目中使用代码的其他部分,因此语言可能是Delphi或C++,但还没有决定.)
自定义线程池的建议大小为number_of_cores + 1(请参见此处和此处).因此,假设在具有2个内核的系统上有一个Spring应用程序,配置就像这样
<task:executor id="taskExecutor"
pool-size="#{T(java.lang.Runtime).getRuntime().availableProcessors() + 1}" />
<task:annotation-driven executor="taskExecutor" />
Run Code Online (Sandbox Code Playgroud)
在这种情况下,将在多个请求之间共享一个ExecutorService.因此,如果10个请求到达服务器,则只能在ExecutorService中同时执行其中3个请求.这可能会产生瓶颈,并且结果会随着请求数量的增加而变得更糟(请记住:默认情况下,tomcat最多可以处理200个并发请求= 200个线程).该应用程序将执行得更好,没有任何池.
通常,一个核心可以同时处理多个线程.例如,我创建了一个服务,它调用两次https://httpbin.org/delay/2.每次调用都需要2秒才能执行.因此,如果没有使用线程池,则服务平均响应4.5秒(使用20个同时请求进行测试).如果使用线程池,则响应因池大小和硬件而异.我在具有不同池大小的4核心机器上运行测试.以下是最小,最大和平均响应时间(以毫秒为单位)的测试结果
从结果可以得出结论,最佳平均时间是最大池大小.池中5(4个核心+ 1)线程的平均时间比没有池的结果更糟糕.因此,在我看来,如果请求不占用大量CPU时间,那么将线程池限制为Web应用程序中的核心数+ 1是没有意义的.
对于非CPU要求的Web服务,是否有人发现在2或4核心机器上将池大小设置为20(甚至更多)有什么问题?