首页 > 解决方案 > 获取双套接字服务器上的可用线程数

问题描述

我需要获取机器上可用 CPU 线程的数量。以前我曾经Runtime.getRuntime().availableProcessors()确定过,它适用于我家里的电脑。它16在我的情况下返回(因为我有一个 8 核、16 线程处理器)。现在我想在具有双插槽配置的服务器上使用该应用程序,两个 Xeon Gold 6154,每个具有 18 个内核/36 个线程。我用来确定线程数量的方式现在给了我36而不是72.

似乎该avaibleProcessors()方法不尊重双插槽配置。

我通过一些研究发现java.util.concurrent.ForkJoinPool.commonPool(),这应该适用于双插槽配置。但是,在我的本地 PC 上,它返回java.util.concurrent.ForkJoinPool@61e717c2[Running, parallelism = 15, size = 0, active = 0, running = 0, steals = 0, tasks = 0, submissions = 0]也就是缺少一个线程……这正常吗?我必须做一些数学运算并将数字加 1 吗?输出的格式也不是很好,我必须做一些正则表达式或类似的操作才能将其转换为可用的格式。

是否有更好的方法来确定机器上的线程数量?还是我现在必须坚持使用 commonPool() 方法?

标签: javahardware

解决方案


默认情况下,如果> 1ForkJoinPool.commonPool()将有线程,否则有 1 个线程。availableProcessors() - 1availableProcessors()

这是 ForkJoinPool.java 源代码的一部分:

if (parallelism < 0 && // default 1 less than #cores
   (parallelism = Runtime.getRuntime().availableProcessors() - 1) <= 0)
        parallelism = 1;

如您所见,它分配Runtime.getRuntime().availableProcessors() - 1parallelism. 因此,如果您有 16 个核心,parallelism则等于15.

availableProcessors()是 jvm 可用的内核数,所以我猜,您的 jvm 仅在双插槽 xeon 的 1 个 cpu 上运行。我不知道如何让它在 2 个 CPU 上运行。

为什么这段 Java 代码没有利用所有 CPU 内核?johnidis 在此线程中的回答建议您在客户端模式下运行 JVM,这就是为什么您只使用一个 CPU,尝试使用-server标志运行它,如果这能解决您的问题,请告诉我。

编辑:我对此进行了更多研究,此链接https://docs.oracle.com/javase/7/docs/technotes/guides/vm/server-class.html建议如果您有 java 5 或更高版本,那么-server选项不需要通过。但是,也许您的流程是使用该-client选项启动的?

此外,这个线程Runtime#availableProcessors() 在 Linux 服务器上没有返回正确的结果表明你的 jvm 可以被限制为,但是/proc/cpuinfo如果你在 linux 上指定了许多处理器。


推荐阅读