拜托,我有点糊涂了。我所知道的是,在现代计算机的普通cpu上,可以并发运行的线程的最大数量从8到16个线程不等。另一方面,使用gpu,数千个线程可以同时运行,而调度程序不会中断任何线程来调度另一个线程。在几个帖子上如:java虚拟机-thr的最大数目eadshttps://community.oracle.com/message/10312772 人们说他们在普通CPU上同时运行数千个java线程。这怎么可能??我如何知道可以并发运行的最大线程数,以便我的代码根据底层体系结构自动调整它。
iyzzxitl1#
所有其他的答案都解释了如何在理论上以内存和其他开销为代价在应用程序中拥有数千个线程。然而值得注意的是,违约 concurrencyLevel 中提供的数据结构 java.util.concurrent 包裹是16。如果你不考虑同样的问题,你会遇到争论的问题。使用比需要的值大得多的值可能会浪费空间和时间,而值小得多的值可能会导致线程争用。确保已设置适当的 concurrencyLevel 以防遇到与线程数较多的并发相关的问题。
concurrencyLevel
java.util.concurrent
30byixjq2#
线程不受可用处理器/内核数量的限制。操作系统调度程序可以在单个cpu上任意数量的线程之间来回切换。这就是“先发制人多任务处理”的含义当然,如果线程数多于内核数,则并非所有线程都将同时执行。有些人会暂停,等待一个时间段。实际上,您可以拥有的线程数量受到调度程序的限制,但是这个数量通常非常高(数千个或更多)。不同的操作系统和不同的版本会有所不同。从性能的Angular 来看,有多少线程是有用的,正如您所说的,这取决于可用处理器的数量以及任务是io还是cpu限制。尝试找到最佳的数字,如果可能的话,使其可配置。
wbrvyc0a3#
在任何给定的时间,处理器运行的线程数等于包含的内核数。这意味着在单处理器系统上,在任何给定时刻只有一个线程(或没有线程)正在运行。然而,处理器并不是一个接一个地运行每个线程,而是在多个线程之间快速切换以模拟并发执行。如果不是这样的话,更不用说创建多个线程,您甚至无法启动多个应用程序。java线程(与处理器指令相比)是cpu要处理的一组指令的高级抽象。当它降到处理器级别时,无法保证在任何给定时间哪个线程将在哪个核上运行。但是考虑到处理器在这些线程之间快速切换,理论上可以创建无限多的线程,尽管这是以性能为代价的。如果你仔细想想,一台现代计算机有数千个线程同时运行(合并所有应用程序),而只有1~16个内核(典型情况)。没有这种任务转换,什么也做不成。如果您正在优化应用程序,那么应该根据手头的工作而不是底层体系结构来考虑所需的线程数量。并行性带来的性能提升应与线程执行开销的增加相对应。由于每台机器都是不同的,每个运行时环境都是不同的,所以计算一些黄金线程数是不切实际的(然而,通过基准测试和查看内核的数量可以做出大致的估计)。
i7uq4tfw4#
存在硬件和软件并发。8到16个线程指的是您拥有的硬件—即一个或多个CPU,这些CPU的硬件可以并行执行8到16个线程。数千个线程指的是软件线程的数量,调度程序必须将它们交换出去,以便每个软件线程都能在硬件上运行。要获取硬件线程数,可以尝试 Runtime.availableProcessors() .
Runtime.availableProcessors()
4条答案
按热度按时间iyzzxitl1#
所有其他的答案都解释了如何在理论上以内存和其他开销为代价在应用程序中拥有数千个线程。然而值得注意的是,违约
concurrencyLevel
中提供的数据结构java.util.concurrent
包裹是16。如果你不考虑同样的问题,你会遇到争论的问题。
使用比需要的值大得多的值可能会浪费空间和时间,而值小得多的值可能会导致线程争用。
确保已设置适当的
concurrencyLevel
以防遇到与线程数较多的并发相关的问题。30byixjq2#
线程不受可用处理器/内核数量的限制。操作系统调度程序可以在单个cpu上任意数量的线程之间来回切换。这就是“先发制人多任务处理”的含义
当然,如果线程数多于内核数,则并非所有线程都将同时执行。有些人会暂停,等待一个时间段。
实际上,您可以拥有的线程数量受到调度程序的限制,但是这个数量通常非常高(数千个或更多)。不同的操作系统和不同的版本会有所不同。
从性能的Angular 来看,有多少线程是有用的,正如您所说的,这取决于可用处理器的数量以及任务是io还是cpu限制。尝试找到最佳的数字,如果可能的话,使其可配置。
wbrvyc0a3#
在任何给定的时间,处理器运行的线程数等于包含的内核数。这意味着在单处理器系统上,在任何给定时刻只有一个线程(或没有线程)正在运行。
然而,处理器并不是一个接一个地运行每个线程,而是在多个线程之间快速切换以模拟并发执行。如果不是这样的话,更不用说创建多个线程,您甚至无法启动多个应用程序。
java线程(与处理器指令相比)是cpu要处理的一组指令的高级抽象。当它降到处理器级别时,无法保证在任何给定时间哪个线程将在哪个核上运行。但是考虑到处理器在这些线程之间快速切换,理论上可以创建无限多的线程,尽管这是以性能为代价的。
如果你仔细想想,一台现代计算机有数千个线程同时运行(合并所有应用程序),而只有1~16个内核(典型情况)。没有这种任务转换,什么也做不成。
如果您正在优化应用程序,那么应该根据手头的工作而不是底层体系结构来考虑所需的线程数量。并行性带来的性能提升应与线程执行开销的增加相对应。由于每台机器都是不同的,每个运行时环境都是不同的,所以计算一些黄金线程数是不切实际的(然而,通过基准测试和查看内核的数量可以做出大致的估计)。
i7uq4tfw4#
存在硬件和软件并发。8到16个线程指的是您拥有的硬件—即一个或多个CPU,这些CPU的硬件可以并行执行8到16个线程。数千个线程指的是软件线程的数量,调度程序必须将它们交换出去,以便每个软件线程都能在硬件上运行。
要获取硬件线程数,可以尝试
Runtime.availableProcessors()
.