Java ExecutorService

3

如何使用ExecutorService以创建一个中央线程池,该线程池在应用程序级别上设置,其池大小根据该时刻CPU可用的线程数进行设置,然后应用程序的不同功能根据自己的要求从该中央池中使用线程。


使用一些自定义包装器来封装ExecutorService,使其成为单例(可能使用依赖注入)? - user180100
1
你可以使用 Runtime.getRuntime().availableProcessors(); 来获取处理器数量,但我不建议这样做。最好通过对代码进行分析来找到最佳线程数。 - Pravin Sonawane
如果你正在寻找一种计算环境可以支持多少线程的方法,这里有一些参考:https://dev59.com/BXRA5IYBdhLWcg3w9y50 - Sagar
这个问题可能对您有用:https://dev59.com/JXI-5IYBdhLWcg3wMFMf#36723383 - Ravindra babu
寻找当前JVM线程计数时也存在问题:需要找到标准的阈值。如果我们采取Happy Case: 如果JVM线程计数小于阈值,则我们将从池中获取线程并处理它。在这种情况下没有问题。但在Sad Case: 如果JVM线程计数大于阈值,该怎么办呢?因此,我们需要等待JVM线程冷却。如果我们正在等待线程,则在CPU利用方面成本过高。如果我们继续等待,则记录过程会累积,并且在性能方面再次成为问题。 - Man
ForkJoinPool似乎适合您的需求。默认情况下,它是使用给定的目标并行度(处理器数量)创建的。 - ak1
2个回答

2

从Java 8开始,我建议您使用ForkJoinPool.commonPool()。这是Java提供的唯一全局线程池。

在Java 8之前,您可以保留自己的线程池或使用框架共享的线程池。


1
以下是我的观点:

  • 一个中央线程池?

    也许,这就像是设计模式中的单例模式,我认为它可以解决你的问题。

  • 根据可用于 CPU 的线程数量设置?

    线程池的大小并非精确。在实践中,大小取决于要由线程池执行的任务类型。例如,如果任务是CPU密集型的,则大小可以为Runtime.getRuntime().availableProcessors() + 1,如果任务是I/O密集型的,则大小可以为Runtime.getRuntime().availableProcessors() * 2。但这些只是基本原则,您应该通过使用一些指南(如Little's_law)测试您的应用程序来确定适当的大小;

  • 我的建议:

    在实践中,我很少将所有任务提交给一个中央线程池,可能应该按类型对任务进行分组,将它们提交到不同的线程池,这样以后监视或调整线程池会更方便。

希望能够帮到你。

谢谢Haolin!还有一个问题,就是在查找当前JVM线程计数时存在的问题:需要找到标准阈值。正常情况:如果JVM线程计数小于阈值,则我们将从池中获取线程并处理它。这种情况下没有问题。异常情况:如果JVM线程计数大于阈值,该怎么办?因此,我们需要等待JVM线程冷却。如果我们在等待线程,那么在CPU利用方面会非常昂贵。如果我们继续等待,那么记录过程就会积累,再次导致性能问题。 - Man

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接