Not really. They could have supported green threads under hotspot, but they chose posix threads, because posix threads were much faster than the previous implementation of green threads.
Today, green threads are faster. Have os threads become slower? Not that I know of. All that’s really changed is how green threads are implemented.
We went from “green threads bad os threads good” to “os threads bad green threads good”. Sure, the new green threads are better than the old ones, but in some alternate universe maybe we could have got here without os threads (and maybe saved hundreds of thousands of hours of developer time in the process).
To me, what’s interesting is that this appears to be a case of evolutionary “local maxima”. Java went from green threads to os threads because os threads gave better performance for the amount of effort expended. But now we’re moving back to green threads - at much greater effort, 20 years later. I’m sure I’m not the only person that wonders what lessons we can learn from this?
> because posix threads were much faster than the previous implementation of green threads.
Green threads employed only one kernel thread so couldn't take advantage of multicore, and at the time Java relied on native code so much more than today.
> but in some alternate universe maybe we could have got here without os threads
Maybe :)
> But now we’re moving back to green threads - at much greater effort, 20 years later
These aren't green threads but M:N, and I don't think it's a much greater effort than the effort that would have been required to add it to HotSpot back then.
Sorry, I'm using the modern meaning of green threads [0], which is simply threads scheduled in userspace.
The first green threads implementation, which was of course Java 1.0, was certainly M:1 - my memory is that we didn't even have pthreads in linux at the time - but the term today doesn't specifically mean a M:1 mapping.
On the other hand, of course JVM1.0 invented "green threads" which was M:1. So yeah this is confusing and I made it more confusing. Sorry. :)
So the point I was trying to make is that Java originally scheduled threads in userspace, then delegated scheduling to the OS, and has now taken it back. In hindsight it seems that delegating this key function to the OS has caused a lot of pain, and I'm interested in the drivers for using OS threads instead of just making the original green thread implementation better.
To be even clearer, I see this a lot in software. We delegate some key function of a product (like database access) to some inefficient and complex machinery (like an ORM) and then spend years working around the problems that decision caused. I've done this myself. I'd like to understand how to stop doing it.
You are largely correct about the "reversion" to userspace threading, but the decisions (some of them were forced moves) weren't because of fashions but very different circumstances. You could point out that it is interesting that different circumstances have led to userspace threads.
I don't know all the reasons behind abandoning green threads, but some are mentioned here: https://docs.oracle.com/cd/E19455-01/806-3461/6jck06gqe/inde... namely, no multi-core and bad FFI ("interoperate with existing MT applications"). Plus, a little later, the transition to HotSpot left little desire to reimplement userspace threading. There was no pressing need, there was other, higher-priority work needed, and FFI was still an impediment. In other words, making green threads better was neither an important requirement nor a reasonable possibility back then.
Why have we "gone back"? 1. the scale of concurrency required today is higher and resulted in the scaffolding I mention in the article, 2. FFI is no longer an impediment as Java code rarely relies on native code these days.
Nevertheless, Project Loom doesn't switch from kernel to userspace threads, but rather lets you choose which implementation you want for each thread.
Green threads are threads which are scheduled in userspace; Java 1 threads were scheduled in userspace, and Loom threads are scheduled in userspace. Loom is absolutely a reversion to userspace scheduling, and I think the intervening decision to delegate scheduling to the OS is something that's interesting to think about, because in hindsight it seems to have been the wrong decision.
(Also, IIRC Linux didn't even have native OS threads when Java 1.0 came out, so M:1 was literally and the only option available in Linux at the time. My memory is that we had to wait for pthreads before we could have hotspot on Linux, but it's a long time ago and quite tangental to my point).
> and I think the intervening decision to delegate scheduling to the OS
This is where you're getting confused.
This wasn't an 'intervening decision' because we haven't removed it and with Loom the OS is still able to schedule your threads. The user-space threads are opt-in. That's why it's not a reversion. Because Java was never like this before.
Today, green threads are faster. Have os threads become slower? Not that I know of. All that’s really changed is how green threads are implemented.
We went from “green threads bad os threads good” to “os threads bad green threads good”. Sure, the new green threads are better than the old ones, but in some alternate universe maybe we could have got here without os threads (and maybe saved hundreds of thousands of hours of developer time in the process).
To me, what’s interesting is that this appears to be a case of evolutionary “local maxima”. Java went from green threads to os threads because os threads gave better performance for the amount of effort expended. But now we’re moving back to green threads - at much greater effort, 20 years later. I’m sure I’m not the only person that wonders what lessons we can learn from this?