2013-01-14 82 views
3

我有一个程序,它并行运行(全天)任务(任务中没有I/O要执行),所以我用Executors.newFixedThreadPool(poolSize)来实现它。Java线程池大小和availableProcessors()

最初,我将poolSize设置为Runtime.getRuntime().availableProcessors(),但由于在同一台PC上运行了其他进程(32个内核),所以我有点担心要使用所有可用的内核。

特别是我有十个其他JVM运行相同的程序(在不同的输入数据上),所以我有点担心在可用内核之间切换线程可能会有很多开销,下整体计算。

我该如何决定每个程序/ JVM池的大小?

此外,在我的电脑中,还有其他进程一直在运行(防病毒,备份等)。我是否也应该考虑到这些?

+0

你只担心自己的计算机上运行此程序?如果是这样,为什么不尝试一个特定的选择,查看您的CPU使用情况,并相应地进行调整。也许你可以在这里发表你的发现。 – BlackVegetable

+4

需要特别注意的是,从Runtime.availableProcessors()''的Javadocs中注意到 - “在特定的虚拟机调用期间,该值可能会发生变化。”换句话说,这种方法不会做你认为它的做法。相反,可以通过属性文件或命令行参数来配置线程池的大小。 – Brian

回答

1

任何建议将取决于您的具体情况。在32个内核上的10个JVM每个会建议3个线程(忽略垃圾收集线程,定时器任务等)。

您还有其他任务正在运行。调度程序将确保它们正在运行,但它们是否必须响应?比JVM响应更快?如果您正在运行Linux/Unix,那么您还可以使用优先级(通过nice)确保特定进程不会占用CPU。

最后,您正在运行10个JVM。会导致分页?如果是这样,那将会很慢,并且为了避免消耗太多内存,您最好不要使用更少的JVM。

只要确保您的关键变量已公开并可配置,并测量各种情况以找到最佳关键变量。

1

我应该如何决定每个程序/ JVM池的大小?

你想要的线程数将使你接近99%的利用率,没有更多。

平衡工作的最简单方法是让进程运行一次,同时处理多个文件并仅使用一个线程池。如果您需要通过命令行启动文件,您可以将其设置为服务处理。

如果由于某种原因这是不可能的,您将需要猜测线程池应该缩减多少。尝试运行一个进程并查看利用率。如果有人说40%,那么我怀疑有10个程序被过度使用了400%。即您可能会将池大小减少4倍。

0

不幸的是,这是一件很难知道的事情,因为程序通常不知道同一个盒子上还有什么或者可能会发生什么。

“简单”的出路是使池大小可配置。这允许控制程序/框的用户决定要分配给程序的线程数量(大概是使用他们对盒子一般工作负载的了解)。

更复杂的解决方案是尝试以编程方式确定框的当前工作负载并从中适当地选择池大小。此解决方案的功效取决于您可以如何准确确定工作负载,并可能随着时间的推移而进行调整。