Evented および Threaded モデルは非常に人気があり、通常はよく議論されます。
すべての I/O 操作をブロックできる「スレッド化」アプローチは、より単純です。同期コードの作成とデバッグは簡単です。実際のところ、ほとんどのエコシステムはブロッキング I/O ライブラリを提供しており、スレッド プールを使用して適切に構成するだけで準備完了です。
しかし..それはスケーリングしません。
そして、ブロックせずに CPU 命令のみを実行するスレッドが 1 つ (または CPU ごとに 1 つ) ある「イベント化」アプローチがあります。IO が戻ると、適切な計算がアクティブになり、CPU の使用率が向上します。
しかし..コーディングが難しく、読み取り不可能なスパゲッティ コードを作成しやすく、非同期 I/O などのための十分なライブラリがありません...そして、ノンブロッキング I/O とブロッキング I/O はうまく混ざりません。ノンブロッキングになるようにゼロから設計されていないエコシステムで使用するのは非常に問題があります。NodeJS では、最初からすべての I/O がノンブロッキングです (javascript には最初から I/O ライブラリがなかったからです)。C++/Java で同じことを実装しようとして頑張ってください。最善を尽くすことはできますが、1 回の同期呼び出しでパフォーマンスが低下します。
そしてゴーがやってきた。Go の同時実行モデルが興味深いことがわかったので、最近 Go を調べ始めました。Go を使用すると、「両方の世界を最大限に活用する」ことができます。すべての I/O はブロックされ、同期コードを記述しながら、CPU を最大限に活用できます。
Go には「Go ルーチン」と呼ばれるスレッドへの抽象化があり、これは基本的にユーザー レベルのスレッドです。「Go ランタイム」(プログラムと共にコンパイルされます) は、実際の OS スレッド (たとえば 1 Go ルーチンがシステム コールを実行するたびに、「Go ランタイム」は別の Go ルーチンを OS スレッドの 1 つで実行するようにスケジュールし、go ルーチンを OS スレッドに「多重化」します。
ユーザーレベルのスレッドは新しい概念ではありません.Goのアプローチは素晴らしくシンプルです.
Sun の 1.2 JVM はそれらをユーザー レベルのスレッドであるグリーン スレッドと呼んでいましたが、単一の OS スレッドに多重化されただけで、マルチコア CPU を利用できるようにするために実際の OS スレッドに移行しました。
これが 1.2 以降の JVM の世界で関連性がなかったのはなぜですか? Go アプローチのマイナス面を見落としているのでしょうか? Go には適用できるが、JVM では実装できない概念があるのではないでしょうか?