我对某事感到困惑。 我所知道的是,在现代计算机的普通CPU上可以并发运行的最大线程数范围为8到16个线程。 另一方面,使用GPU可以同时运行数千个线程,而调度程序不会中断任何线程来安排另一个线程。 在几个帖子上: Java virtual machine - maximum number of threads https://community.oracle.com/message/10312772 人们说它们在普通的CPU上同时运行数千个java线程。 这怎么可能? 我怎么知道可以并发运行的最大线程数,以便我的代码根据底层架构自动调整它。
答案 0 :(得分:9)
线程不受可用处理器/核心数量的限制或限制。操作系统调度程序可以在单个CPU上的任意数量的线程之间来回切换。这就是"抢先式多任务处理的意思。"
当然,如果你有比核心更多的线程,并非所有线程都会同时执行 。有些人将被搁置,等待一个时间段。
实际上,您可以拥有的线程数受到调度程序的限制 - 但这个数字通常非常高(数千或更多)。它将因操作系统和操作系统以及各个版本而异。
从性能角度来看,有多少线程有用,正如您所说,它取决于可用处理器的数量以及任务是IO还是CPU绑定。尝试找到最佳数字并尽可能使其可配置。
答案 1 :(得分:4)
有硬件和软件并发。 8到16个线程指的是您拥有的硬件 - 即一个或多个CPU,其硬件可以执行8到16个彼此并行的线程。成千上万的线程指的是软件线程的数量,调度程序必须将它们交换出来,以便每个软件线程都获得在硬件上运行的时间片。
要获取硬件线程数,您可以尝试Runtime.availableProcessors()
。
答案 2 :(得分:1)
在任何给定时间,处理器将运行的线程数等于包含的核心数。这意味着在单处理器系统上,在任何给定时刻只运行一个线程(或没有线程)。
但是,处理器不会一个接一个地运行每个线程,而是在多个线程之间快速切换以模拟并发执行。如果不是这种情况,更不用说创建多个线程,您甚至无法启动多个应用程序。
java线程(与处理器指令相比)是CPU处理的一组指令的非常高级的抽象。当它下降到处理器级别时,无法保证在任何给定时间哪个线程将在哪个核心上运行。但鉴于处理器在这些线程之间快速切换,理论上可以创建无限量的线程,尽管代价是性能。
如果你考虑一下,现代计算机有数千个线程同时运行(组合所有应用程序),而只有1~16(典型情况)的核心数。如果没有这项任务转换,任何事情都无法完成。
如果要优化应用程序,则应考虑手头工作所需的线程数量,而不是基础架构。并行性带来的性能增益应该加权来增加线程执行的开销。由于每台机器都不同,每个运行时环境都不同,计算一些黄金线程计数是不切实际的(但是,可以通过基准测试和查看核心数来估算球场)。
答案 3 :(得分:0)
尽管所有其他答案都说明了从理论上讲您如何才能在应用程序中拥有数千个线程,却以内存为代价,而其他开销也已经得到了很好的解释here。但是,值得注意的是,concurrencyLevel
包中提供的数据结构的默认java.util.concurrent
为16。
如果您不解释这一点,就会遇到争用问题。
使用大大高于所需的值会浪费空间和时间,而大大降低的值会导致线程争用。
请确保已设置适当的concurrencyLevel
,以防遇到与线程数更多的并发相关的问题。