39

Whilst I know questions on this have been covered already (e.g. https://stackoverflow.com/questions/5713142/green-threads-vs-non-green-threads), I don't feel like I've got a satisfactory answer.

The question is: why don't JVM's support green threads anymore?

It says this on the code-style Java FAQ:

A green thread refers to a mode of operation for the Java Virtual Machine (JVM) in which all code is executed in a single operating system thread.

And this over on java.sun.com:

The downside is that using green threads means system threads on Linux are not taken advantage of and so the Java virtual machine is not scalable when additional CPUs are added.

It seems to me that the JVM could have a pool of system processes equal to the number of cores, and then run green threads on top of that. This could offer some big advantages when you have a very large number of threads which block often (mostly because current JVM's cap the number of threads).

Thoughts?

redjamjar
  • 819
  • 1
  • 7
  • 10
  • 6
    To me, the question seems: Why green threads? Why re-introduce multithreading by emulating it at JVM level via multiple processes? It's a lot of pain and overhead for seemingly no gain other than allowing programmers being more generous with spawning threads (and I'm not convinced that's an advantage). –  Nov 17 '11 at 21:42
  • 4
    Well, it's about having a concurrent programming model which scales. Currently, in Java, if you want scalability you switch to NIO with your own thread pool. At least, that's my understanding. – redjamjar Nov 17 '11 at 21:45
  • 3
    The presence of things like which supports lightweight threads also makes me think there is a need. Actually, just found quite a good discussion here – redjamjar Nov 17 '11 at 21:48
  • 2
    @delnan Because context switch for native threads costs. Green threads have much less overhead for context switch and interprocess syncs. In addition, the amount of green threads is practically unlimited (it can be hundreds of thousands of them without too much stress for VM process), while amount of native threads is restricted by OS and memory overhead. – permeakra Jul 21 '13 at 09:42
  • It took a long time before the JVM supported native threads directly. Green threads was the intermediate solution until then. – Thorbjørn Ravn Andersen Mar 02 '16 at 22:03
  • This is a really good question - lots of languages are going this way, at least optionally, and Java is a great candidate for it as well especially with the nio libraries. Green threads let the developer take care of the concurrency and the runtime the parallelism, which can be pretty great. – Rob Grant Oct 18 '16 at 05:37
  • The JVM is looking to add green threads (now called 'fibers') back again in Project Loom, so it looks like the JVM devs agree with you. – JanKanis May 05 '21 at 20:20

3 Answers3

33

I remember the JVM abandoning green threads and moving to native threads. This was for two simple reasons: the green threads were frankly rubbish, and there was a need to support multi-core processors with the limited developer effort available at Sun.

This was a shame - green threads provide a far better abstraction, allowing concurrency to be a useful tool not a stumbling block. But green threads are no use if several hurdles can't be overcome:

  • they must use all the cpu cores available to them

  • context switching must be cheap

  • I/O may block any thread engaged in it, but not any other thread and certainly not all other threads, which was the case in some early implementations.

I've often wondered why multi-threading is so hard in Java but it's now becoming clearer - it was ultimately to do with the switch to native threads, which are:

  • good at using all the cpu cores

  • good at being truly concurrent, providing independent I/O etc

  • slow at context switching (compared with the best green thread implementations)

  • horribly greedy with memory, hence limiting the maximum usable number of them

  • a poor abstraction for any basis for expressing the real world, which is highly concurrent of course.

Nowadays, a lot of programmer time now goes into coding up non-blocking I/O, futures etc. It's a big shame we don't have a better level of abstraction.

For comparison, besides Erlang the new Go language does a good job of huge concurrency. The grand-daddy of them all remains Occam, still an ongoing research project.

Rick-777
  • 431
  • 4
  • 4
  • 1
    how far have we gone since the time you posted :O – Dmytro Dec 07 '16 at 22:29
  • 3
    Alas, Rust is another language that abandoned better concurrency abstractions. They too decided to move from co-operative threads to native threads. – Rick-777 Dec 07 '16 at 23:57
  • 3
    @Rick-777 Rust is too low-level to do that. – Malcolm Jan 29 '17 at 17:29
  • @Rick-777 https://doc.rust-lang.org/book/ch16-01-threads.html#using-threads-to-run-code-simultaneously this explains why Rust did not chose green threads. tl;dr, implementing green thread for itself will increase the compiled binary size, and Rust wants a small binary instead. – Peter Paul Apr 16 '21 at 14:09
16

A single process faking multiple threads has a lot of problems. One of them is that all the faked threads stall on any page fault.

The alternative that you suggest, a pool of processes, has some advantages and some disadvantages. The biggest advantage, isolation of the 'threads', really wouldn't get you much here. The big disadvantage, extreme difficulty of implementation and less efficient synchronization, is the deal-killer here.

However, I do agree that there exist some applications (not Java) where a pool of processes that you could use like a pool of threads (but with more isolation) would be a great thing to have. Threads share pretty much everything. With processes, you can specifically choose what to share. To my knowledge, nobody has gone to the effort of implementing it yet.

David Schwartz
  • 4,676
  • 22
  • 26
  • Occam claims to offer this. It was a significant language in the '80s, but suffered from lack of development funding and consequently became a research niche only. But its ideas on concurrency are as solid now as they were then and are yet to be improved upon. – Rick-777 Sep 15 '14 at 22:47
  • If you are "multi threaded" a la golang ("M:N" type scheduling) then theoretically only one green thread is blocked by a page fault because the other threads can "pick up the slack" (other green threads) it seems... https://softwareengineering.stackexchange.com/questions/222642/are-go-langs-goroutine-pools-just-green-threads – rogerdpack Aug 24 '18 at 17:22
15

There'll be no benefit at all for an average Java code. Java is not Erlang, and Java programmers are not in the same mindset as Erlang programmers. The language was never intended to be used this way.

If you want the true lightweight processess - use Erlang and create thousands of threads communicating via messages. In Java you'll have a dozen of threads sharing a common memory with mutexes and semaphores. It is just a different programming model, designed for a different set of problems.

SK-logic
  • 8,497
  • 4
  • 25
  • 37
  • So, to clarify though, it is a useful approach in Erlang. And, ignoring the issues of the Java mindset, it could actually help? – redjamjar Nov 18 '11 at 02:43
  • 1
    @redjamjar, it is unlikely to be useful in Java, language itself is not quite suitable for such a use, and its main (and only) advantage - the vast body of ready to use libraries - won't fit well into such an alien programming approach. – SK-logic Nov 18 '11 at 03:05
  • Yea if you want that model, just use Erlang, it will be an order of magnitude easier – Zachary K Apr 20 '12 at 12:16
  • 1
    Java != JVM, just saying :) – Kamil Tomšík Nov 21 '12 at 21:18
  • "And only advantage"? Java has many advantages... Portability, WORA, (IMO) the design itself is nice, etc. – jcora Nov 22 '12 at 12:36
  • 1
    @Bane, these "advantages" only exist if you've got nothing to compare – SK-logic Nov 22 '12 at 13:29