5

Evented 和 Threaded 模型非常流行,并且经常被讨论。

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

但是..它没有扩展。

然后是“事件”方法,其中有一个线程(或每个 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”的线程有一个抽象,它基本上是用户级线程,“Go Runtime”(与您的程序一起编译)负责在真实 OS 线程上调度不同的 Go Routines(比如说 1每个 CPU)每当 Go 例程执行系统调用时,“Go Runtime”会安排另一个 Go 例程在其中一个 OS 线程中运行,它会将 Go 例程“多路复用”到 OS 线程上。

用户级线程不是一个新概念,Go 的方法很好,也很简单,所以我开始想,为什么 JVM 世界不使用类似的抽象,与通常在引擎盖下发生的事情相比,这只是孩子的游戏。

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


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

4

0 回答 0