Evented,Threaded和Go Routines,为什么不使用更多?

Mat*_*tan 5 java concurrency multithreading jvm go

Evented和Threaded模型很受欢迎,通常会讨论很多.

每个I/O操作都可以阻塞的"线程"方法更简单.编写和调试同步代码更容易,事实上大多数生态系统提供了阻塞I/O库,只需使用线程池,正确配置它就可以了.

但是......它没有扩展.

然后是'Evented'方法,其中有一个线程(或每个cpu一个)永远不会阻塞并仅执行CPU指令.当IO返回时,它会激活适当的计算,从而更好地利用CPU.

但是......代码更难编写,更容易创建不可读的意大利面条代码,没有足够的库用于异步I/O等......非阻塞和阻塞I/O不能很好地混合.在生态系统中使用非常有问题,这些生态系统并非从头开始设计为非阻塞.在NodeJS中,所有I/O从一开始就是非阻塞的(因为javascript从未有过I/O库).祝你在C++/Java中实现同样的功能.你可以尽力而为,但需要一个同步调用来扼杀你的表现.

然后来了Go.我最近开始研究Go因为我发现它的并发模型很有趣.Go使您能够"充分利用两个世界",所有I/O都阻塞,编写同步代码,但享受CPU的充分利用.

Go有一个名为'Go Routines'的Threads抽象,它基本上是用户级线程,'Go Runtime'(用你的程序编译)负责在实际操作系统线程上调度不同的Go Routines(比方说1)每个CPU执行一个系统调用时,'Go Runtime'计划另一个Go Routine在一个OS线程中运行,它将go-routines'多路复用'到OS线程上.

用户级线程不是一个新概念,Go的方法很好,而且很简单,所以我开始想知道,为什么JVM世界不使用类似的抽象,它与孩子的游戏相比,通常发生在幕后.

然后我发现它确实如此,Sun的1.2 JVM称它们是绿色线程,它们是用户级线程,但是它们只被复用到一个OS线程中,它们转移到真正的OS线程以允许使用多核CPU.


在1.2之后,为什么这与JVM世界无关?我没有看到Go方法的缺点吗?也许某些概念适用于Go,但是不能在JVM上实现?