java线程切换需要多长时间?

java线程切换需要多长时间?,java,reactive-programming,Java,Reactive Programming,我正在学习反应式编程技术,包括异步I/O等,但我找不到关于不切换线程的好处的权威对比数据 显然,与计算相比,切换线程是“昂贵的”。但我们谈论的是什么规模 基本问题是“切换一个java线程需要多少处理器周期/指令?”(我期待一个范围) 它受操作系统的影响吗? 我认为它受线程数量的影响,这就是为什么异步IO比阻塞要好得多的原因——线程越多,上下文必须存储得越远(可能甚至从缓存中存储到主内存中) 我已经看到,虽然它已经过时了,但对于关联处理器周期可能仍然有用(网络可能需要更多的“指令”,SSD磁盘可能

我正在学习反应式编程技术,包括异步I/O等,但我找不到关于不切换线程的好处的权威对比数据

显然,与计算相比,切换线程是“昂贵的”。但我们谈论的是什么规模

基本问题是“切换一个java线程需要多少处理器周期/指令?”(我期待一个范围)

它受操作系统的影响吗? 我认为它受线程数量的影响,这就是为什么异步IO比阻塞要好得多的原因——线程越多,上下文必须存储得越远(可能甚至从缓存中存储到主内存中)

我已经看到,虽然它已经过时了,但对于关联处理器周期可能仍然有用(网络可能需要更多的“指令”,SSD磁盘可能更少)

我知道反应式应用程序可以使web应用程序每秒(每台服务器)的请求数从1000到10000,但这也很难说——欢迎评论


注意-我知道目前这是一个模糊、无用、模糊的问题,因为我不知道会影响上下文切换速度的输入。也许统计答案会有所帮助——例如,我猜>=60%的线程需要100-10000个处理器周期才能切换

鲁格尔说得有道理。在现代建筑中,理论上的周转时间通常与实际测量值相差甚远,因为硬件和软件都变得非常复杂。它本身也取决于您的应用程序。例如,许多web应用程序都是I/O绑定的,上下文切换时间的重要性要小得多


还要注意(您称之为线程切换)是操作系统的事情,而不是Java的事情。无法保证操作系统中的上下文切换有多“重”。过去,执行一个任务需要几十个甚至几十万个CPU周期,但也有一些系统和实验系统,即使是内核级的切换也只需要几百个周期。

线程切换是由操作系统完成的,因此Java与之无关。另外,至少在linux上,但我认为还有许多其他操作系统,调度成本并不取决于线程的数量。Linux从2.6版开始就使用调度器

Linux上的线程切换开销是(2018年的文章)。不幸的是,本文没有列出测量的时钟速度,但是开销应该是1000-2000个时钟周期左右。在给定的机器和操作系统上,线程切换开销应该或多或少是恒定的,而不是大范围的

除了这种直接切换成本外,还有改变工作负载的成本:新线程最有可能使用不同的指令和数据集,这些指令和数据需要加载到缓存中,但线程切换或异步编程“上下文切换”之间的成本没有区别。为了完整性,切换到完全不同的进程会增加更改内存地址空间的额外开销,这一点也很重要

相比之下,Go编程语言中Goroutine之间的切换开销(使用非常类似于异步编程技术的用户空间线程)约为170 ns,因此是linux线程切换的七分之一

当然,这对您是否重要取决于您的用例。但是对于大多数任务,您花费在计算上的时间将远远超过上下文切换开销。除非你有很多线程在切换前只做很少的工作

自21世纪初以来,线程开销有了很大的提高,根据链接文章,在生产环境中运行10000个线程在一个内存非常大的服务器上应该不是问题。关于线程切换速度慢的一般说法通常是基于过去的计算机,所以就拿那些持保留态度的计算机来说吧


异步编程剩下的一个基本优势是用户空间调度器对任务有更多的了解,因此原则上可以做出更明智的调度决策。它也不必处理来自不同用户的进程,这些用户做的事情大不相同,仍然需要公平地安排。但即使这样也可以解决问题,通过正确的内核扩展,我们能够将线程切换开销降低到与goroutine交换机相同的范围(200 ns)。

y您自己不做一个测量,并与我们共享吗?这将是有用的!因为基准测试充满了困难。即使我知道如果我不使用,我会把事情搞得一团糟,但我认为线程切换是很难指定的。我正在寻找应用程序的典型值(我想主要是web),这不容易设置。为了有效地进行基准测试,我需要知道影响性能的维度,我只能猜测#个本地引用、#个寄存器、缓存大小、线程数、锁、共享变量等。这是一个好的开始!我专门使用“java线程”作为它的术语,因为这是我所在的平台。我知道它(历史上)比进程切换快,但它是否完全等同于上下文切换?在我看来,你的第二段说“java线程上下文切换”确实是一个很好的限制,而不是“通用上下文切换”@Stephen java只是为低级系统线程提供了一个高级API。如果您查看JVM源代码,您很可能会发现Thread类只是调用底层代码。是的,这是我认识的术语(从几年前;)