前提知識
- Javaのスレッド処理にはJavaスレッドとOSスレッドの二種類が存在する
- Javaスレッド
- JVM内で生成されるスレッド
- java.lang.Threadクラスで生成する
- Javaスレッド自体は処理を実行しない
- OSスレッド
- OSが管理するスレッド
- Javaスレッドとマッピングされ、Javaアプリの処理を実行する
グリーンスレッド
グリーンスレッドモデルでは、JavaスレッドとOSスレッドがN対1で紐づきます。
OS側が1なので、シングルコアCPUに適したモデルです。
Java 1.0がリリースされた頃、CPUはシングルコアの時代でした。
CPUのコア数については以下記事が一番わかり易いと思ってます。
CPUのコアを厨房のシェフに例えると、
- クロック数・・・シェフ1人あたりの仕事の速さ
- コア数・・・シェフの人数
- スレッド数・・・シェフ1人が利用するコンロ数
と言えます。
ネイティブスレッド
ネイティヴスレッドモデルでは、JavaスレッドとOSスレッドが1対1で紐づきます。
Javaスレッド側がNから1に減ったのでスループットが落ちたように見えますが、そんなことはありません。
実際は1対1の組のスレッドを大量に生成し、OS側に複数スレッドを処理させています。
これは、CPUがマルチコアになったゆえできる芸当です。
M:N
M:Nモデルはその名の通り、JavaスレッドとOSスレッドがM対Nで紐づきます。
ただし、M>Nです。
Java 21からGAされたVirtual Threads(仮想スレッド)はこのスレッドモデルを採用しています。
従来のネイティヴスレッドではスレッドを1つ生成するたびにOS側でスレッドが増えます。
OSスレッドはシステムコールで生成され、カーネルモードで管理されるので負荷が高くなります。
またコア数以上のスレッドを生成した際のコンテキストスイッチの負荷も高いです。
そうした辛さを克服するためのスレッドモデルがM:Nモデルです。
JavaのVirtual ThreadsはJVMで管理されるので、OSスレッドに比べて負荷が少ないです。
(JVMはユーザーモードで操作できる)
Virtual Threadsは軽量なのでJVMが許す限りは大量に生成できます。どのVirtual ThreadsがどのOSスレッドの処理を実行するかもJVMがスケジューリングします。
参考リンク