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?

7
  • 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).
    – user7043
    Commented Nov 17, 2011 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
    Commented Nov 17, 2011 at 21:45
  • 3
    The presence of things like <akka.io> which supports lightweight threads also makes me think there is a need. Actually, just found quite a good discussion here <stackoverflow.com/questions/7458782/…>
    – redjamjar
    Commented Nov 17, 2011 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
    Commented Jul 21, 2013 at 9:42
  • It took a long time before the JVM supported native threads directly. Green threads was the intermediate solution until then. Commented Mar 2, 2016 at 22:03

3 Answers 3

35

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.

4
  • 2
    how far have we gone since the time you posted :O
    – Dmytro
    Commented Dec 7, 2016 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
    Commented Dec 7, 2016 at 23:57
  • 3
    @Rick-777 Rust is too low-level to do that.
    – Malcolm
    Commented Jan 29, 2017 at 17:29
  • @Rick-777 doc.rust-lang.org/book/… 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
    Commented Apr 16, 2021 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.

2
  • 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
    Commented Sep 15, 2014 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... softwareengineering.stackexchange.com/questions/222642/…
    – rogerdpack
    Commented Aug 24, 2018 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.

6
  • So, to clarify though, it is a useful approach in Erlang. And, ignoring the issues of the Java mindset, it could actually help?
    – redjamjar
    Commented Nov 18, 2011 at 2: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
    Commented Nov 18, 2011 at 3:05
  • Yea if you want that model, just use Erlang, it will be an order of magnitude easier
    – Zachary K
    Commented Apr 20, 2012 at 12:16
  • 1
    Java != JVM, just saying :) Commented Nov 21, 2012 at 21:18
  • 1
    @Bane, these "advantages" only exist if you've got nothing to compare
    – SK-logic
    Commented Nov 22, 2012 at 13:29

Not the answer you're looking for? Browse other questions tagged or ask your own question.