事件化,线程化和执行例程,为什么不多使用? [关闭]

The Evented and Threaded models are quite popular and are usually discussed a lot.

The 'Threaded' approach, where every I/O operation can block, is simpler. It's easier to write and debug synchronous code, and the fact of the matter is that most ecosystems provide blocking I/O libraries, just use a thread pool, configure it properly and you're good to go.

But.. it doesn't scale.

And then there's the 'Evented' approach, where there is one thread (or one per cpu) that never blocks and performs only CPU instructions. When IO returns, it activates the appropriate computation, allowing better utilization of the CPU.

But.. it's harder to code, easier to create unreadable spaghetti code, there aren't enough libraries for async I/O etc... And non-blocking and blocking I/O don't mix well. It's very problematic to use in ecosystems that weren't designed from the ground up to be non-blocking. In NodeJS all I/O is non-blocking from the beginning (because javascript never had an I/O library to begin with). Good luck trying to implement the same in C++/Java. You can try your best, but it would take one synchronous call to kill your performance.

And then came Go. I started looking into Go recently because i found it's concurrency model interesting. Go gives you the ability to "get the best out of both worlds", all I/O is blocking, write synchronous code, but enjoy the full utilization of the CPU.

Go has an abstraction to Threads called 'Go Routines', which are basically user level threads, the 'Go Runtime' (which gets compiled in with your program) is in charge of scheduling the different Go Routines on real OS threads (let's say 1 per CPU) whenever a Go Routine performs a system call the 'Go Runtime' schedules another Go Routine to run in one of the OS threads, it 'multiplexes' the go-routines onto the OS threads.

User level threads isn't a new concept, Go's approach is nice, and simple, so I started wondering, why doesn't the JVM world use a similar abstraction, it's child's play compared to what usually happens there under the hood.

Then I found out it did, Sun's 1.2 JVM called them green threads which were user level threads, but the were only multiplexed into a single OS thread, they moved on to real OS threads to allow utilizing multi-core CPU's.


Why wasn't this relevant in the JVM world after 1.2? Am I failing to see the downsides of the Go approach? Maybe some concept that applies to Go, but would not be implementable on the JVM?