繁体   English   中英

在 CPU 上的 Java 中可以并发运行的最大线程数

[英]Maximum number of threads than can run concurrently in java on a CPU

请我对某事感到困惑。 我所知道的是,现代计算机的普通 CPU 上可以同时运行的最大线程数为 8 到 16 个线程。 另一方面,使用 GPU 可以同时运行数千个线程,而无需调度程序中断任何线程来调度另一个线程。 在几个帖子中: Java 虚拟机 - 最大线程数https://community.oracle.com/message/10312772人们声称他们在普通 CPU 上同时运行数千个 Java 线程。 这怎么可能?? 以及如何知道可以同时运行的最大线程数,以便我的代码根据底层架构动态调整它。

线程不受可用处理器/内核数量的约束或限制。 操作系统调度程序可以在单个 CPU 上的任意数量的线程之间来回切换。 这就是“抢占式多任务处理”的含义。

当然,如果你有超过内核更多的线程,并不是所有的线程将被同时执行。 有些将被搁置,等待一个时间段。

实际上,您可以拥有的线程数受到调度程序的限制 - 但该数量通常非常高(数千或更多)。 它会因操作系统和个人版本而异。

至于从性能的角度来看有多少线程有用,正如您所说,这取决于可用处理器的数量以及任务是 IO 还是 CPU 受限。 尝试找到最佳数量,并在可能的情况下使其可配置。

存在硬件和软件并发。 8 到 16 个线程是指您拥有的硬件 - 即一个或多个带有硬件的 CPU,可以并行执行 8 到 16 个线程。 数千个线程是指软件线程的数量,调度程序必须将它们换出,以便每个软件线程都有自己的时间片在硬件上运行。

要获得硬件线程的数量,您可以尝试Runtime.availableProcessors()

在任何给定时间,处理器将运行与包含的内核数相等的线程数。 这意味着在单处理器系统上,在任何给定时刻只有一个线程(或没有线程)正在运行。

然而,处理器并不是一个接一个地运行每个线程,而是在多个线程之间快速切换以模拟并发执行。 如果不是这种情况,更不用说创建多个线程了,您甚至无法启动多个应用程序。

Java 线程(与处理器指令相比)是 CPU 处理的一组指令的非常高级的抽象。 当它下降到处理器级别时,无法保证在任何给定时间哪些线程将在哪个内核上运行。 但考虑到处理器在这些线程之间快速切换,理论上可以创建无限数量的线程,尽管以性能为代价。

如果您考虑一下,现代计算机有数千个线程同时运行(结合所有应用程序),而只有 1 到 16 个(典型情况)内核数。 如果没有这种任务切换,就什么也做不了。

如果您正在优化您的应用程序,您应该根据手头的工作而不是底层架构来考虑您需要的线程数量。 并行性带来的性能提升应该权衡增加的线程执行开销。 由于每台机器都不同,每个运行时环境都不同,因此计算出一些黄金线程数是不切实际的(但是,可以通过基准测试和查看内核数量来进行大致估计)。

虽然所有其他答案都解释了理论上如何以内存和其他开销为代价在应用程序中拥有数千个线程,但这里已经很好地解释 然而值得注意的是, java.util.concurrent包中提供的数据结构的默认concurrencyLevel是 16。

如果您不考虑相同的问题,您将遇到争用问题。

使用明显高于您需要的值会浪费空间和时间,而明显较低的值会导致线程争用。

确保您已设置适当的concurrencyLevel ,以防您遇到与具有更多线程的并发相关的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM