为什么不绿线?


33

虽然我知道有关此问题的问题已经解决(例如https://stackoverflow.com/questions/5713142/green-threads-vs-non-green-threads),但我感觉自己并没有一个令人满意的答案。

问题是:为什么JVM不再支持绿色线程?

它在代码样式的Java FAQ上说了这一点:

绿色线程是指Java虚拟机(JVM)的一种操作模式,其中所有代码都在单个操作系统线程中执行。

然后在java.sun.com上

不利之处在于,使用绿色线程意味着Linux上的系统线程无法得到利用,因此当添加其他CPU时Java虚拟机无法扩展。

在我看来,JVM可以具有等于内核数量的系统进程池,然后在此之上运行绿色线程。当您有大量经常阻塞的线程时(这可能是由于当前JVM限制了线程数),这可能会带来一些很大的优势。

有什么想法吗?


5
在我看来,问题似乎是:为什么要使用绿色螺纹?为什么通过通过多个进程在JVM级别上模拟多线程来重新引入多线程?除了让程序员更慷慨地使用派生线程外,似乎没有任何收获,这是很多痛苦和开销的事情(而且我不认为这是一个优势)。

4
好吧,这是关于具有可扩展规模的并发编程模型的。当前,在Java中,如果要扩展性,可以使用自己的线程池切换到NIO。至少,这是我的理解。
redjamjar

3
支持轻量级线程的< akka.io >之类的东西也使我认为有必要。实际上,刚刚在这里找到了很好的讨论< stackoverflow.com/questions/7458782/… >
redjamjar 2011年

2
@delnan因为本机线程的上下文切换需要花费。对于上下文切换和进程间同步,绿色线程的开销要少得多。此外,绿色线程的数量实际上是无限的(可以有成千上万的绿色线程,而不会给VM进程带来太大的压力),而本机线程的数量则受操作系统和内存开销的限制。
permeakra

JVM花了很长时间才直接支持本机线程。在此之前,绿色线程是中间解决方案。
托尔比约恩Ravn的安德森

Answers:


29

我记得JVM放弃了绿色线程,而转向了本机线程。这有两个简单的原因:绿色线程坦率地说是垃圾,并且有必要在Sun有限的开发人员支持下支持多核处理器。

真可惜-绿色线程提供了更好的抽象,允许并发成为有用的工具,而不是绊脚石。但是,如果无法克服几个障碍,绿色线程就没有用:

  • 他们必须使用所有可用的CPU核心

  • 上下文切换必须便宜

  • I / O可以阻止参与其中的任何线程,但不能阻止任何其他线程,当然也不能阻止所有其他线程,这在某些早期实现中就是这种情况。

我经常想知道为什么Java中的多线程处理如此困难,但是现在变得越来越清晰-最终与切换到本机线程有关:

  • 善于使用所有cpu核心

  • 善于真正并发,提供独立的I / O等

  • 上下文切换速度较慢(与最佳的绿色线程实现相比)

  • 对内存的贪婪程度极高,因此限制了它们的最大可用数量

  • 表示现实世界的任何基础的抽象都很差,这当然是高度并行的。

如今,大量的程序员时间都花在了编写无阻塞I / O,期货等方面的代码。很遗憾我们没有更好的抽象水平。

为了进行比较,除了Erlang之外,新的Go语言还很好地完成了巨大的并发性。他们的祖父仍然是Occam,仍然是一个正在进行的研究项目。


自您发布以来,我们走了多远:O
德米特里(Dmitry)

3
Rust,Rust是另一种放弃更好的并发抽象的语言。他们也决定从合作线程转移到本地线程。
Rick-777

2
@ Rick-777 Rust太底层了,无法做到这一点。
马尔科姆

15

伪造多个线程的单个进程存在很多问题。其中之一是,所有伪造的线程都会在任何页面错误时停止运行。

您建议的替代方案是一个过程池,它既有优点也有缺点。最大的优势是,“线程”的隔离实际上并不会帮助您。最大的缺点是实施的极端困难和同步效率较低,这是这里的杀手er。

但是,我确实同意存在某些应用程序(不是Java),您可以使用像线程池(但具有更多隔离性)这样的进程池是一件很棒的事情。线程几乎共享所有东西。使用流程,您可以专门选择要共享的内容。据我所知,还没有人致力于实现它。


Occam声称提供了这一点。它在80年代是一门重要的语言,但由于缺乏开发资金而受苦,因此仅成为研究领域。但是它关于并发的思想现在和那时一样牢固,并且有待改进。
Rick-777

如果您是“多线程”的la golang(“ M:N”类型调度),那么理论上只有一个绿色线程被页面错误阻止,因为看起来其他线程可以“拾取松弛”(其他绿色线程)。 .. softwareengineering.stackexchange.com/questions/222642/...
rogerdpack

13

一般的Java代码完全没有好处。Java不是Erlang,Java程序员与Erlang程序员的想法不同。从未打算以这种方式使用该语言。

如果您想要真正的轻量级进程,请使用Erlang并创建数千个通过消息进行通信的线程。在Java中,您将有十几个线程与互斥量和信号量共享一个公共内存。它只是针对不同问题而设计的不同编程模型。


因此,尽管要澄清一下,它是Erlang中的一种有用方法。而且,如果不考虑Java思维方式的问题,它实际上会有所帮助吗?
redjamjar

1
@redjamjar,它不太可能在Java中使用,语言本身不太适合这种用途,它的主要(也是唯一)优势-大量可立即使用的库-不太适合此类应用编程方法。
SK-logic

是的,如果您要使用该模型,只需使用Erlang,将容易一个数量级
Zachary K

1
Java!= JVM,只是说:)
KamilTomšík2012年

1
@Bane,这些“优点”只有在您没有什么可比较的情况下才存在
SK-logic
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.