コンピュータプログラミングにおいて、仮想スレッドとは、ランタイムライブラリまたは仮想マシン(VM)によって管理され、その上で実行されるコードに対してカーネルスレッドに似た動作をするように設計されたスレッドであり、カーネルスレッドよりも大幅に少ないリソースで動作します。
仮想スレッドにより、2021年の一般消費者向けコンピュータでは数千万のプリエンプティブタスクとイベントが可能になります[ 1 ] 。これは、オペレーティングシステムのスレッドが数千程度であるのと比較すると非常に多いです[ 2 ] 。プリエンプティブ実行[ 3 ]は、並列処理によるパフォーマンスの向上と、数千万のイベントに対する高速なプリエンプティブ応答時間にとって重要です。
コルーチン、グリーンスレッド、あるいはほぼシングルスレッドのNode.jsなど、プリエンプティブではない、あるいは常にプリエンプティブではない従来の構造では、サーバーアプリケーションにおけるすべての受信リクエストなどの非同期イベントへの応答に遅延が生じる。[ 4 ]
仮想スレッドはプリエンプティブです
仮想スレッドは、すべてのプロセッサとコアの実行ユニットを飛び越えることができる。
仮想スレッドは、プログラマによるyieldや同様の介入を必要としません。
仮想スレッドは、多くの場合管理された小さなスタックを特徴とすることで、数千万個に達する可能性がある。
仮想スレッドは迅速に割り当てることができます
仮想スレッドは、オペレーティングシステムのスレッドと同様にメモリを共有します。
仮想スレッドは、オペレーティングシステムのスレッドのように並列処理を提供する。
Javaサーバーは、仮想スレッドを使用せずに、数十個のプールされたオペレーティングシステムスレッドが毎秒数千のリクエストを先取りして実行できるようにする、広範かつメモリを消費するソフトウェア構造を備えています。ここでのパフォーマンスの鍵は、スレッド処理の初期レイテンシを削減し、オペレーティングシステムスレッドがブロックされる時間を最小限に抑えることです。[ 6 ]
仮想スレッドは可能な並行性を何桁も増加させますが、実際に達成される並列性は、現在のプロセッサとプロセッサコアが提供する実行ユニットとパイプライン処理によって制限されます。2021年現在、一般消費者向けコンピュータは通常、数十の同時実行ユニットの並列性を提供します。 [ 7 ]並列性によるパフォーマンス向上のためには、言語ランタイムはすべての現在のハードウェアを使用する必要があり、[ 8 ]シングルスレッドであってはならず、グローバルインタプリタロックなどのグローバル同期機能を備えていなければなりません。
仮想スレッドによって提供されるプリエンプティブ項目の増加は、言語ランタイムがサイズ変更可能なスレッドスタックを管理することによって実現されます。[ 9 ]これらのスタックは、オペレーティングシステムのスレッドのスタックよりもサイズが小さくなっています。スワッピングなしで可能なスレッドの最大数は、メインメモリの量に比例します。[ 10 ]
仮想スレッドを効率的にサポートするためには、言語ランタイムを大幅に書き換えて、仮想スレッドを実行するように割り当てられたオペレーティングシステムスレッドをブロッキング呼び出しでブロックしないようにし[ 11 ]、スレッドスタックを管理する必要があります[ 12 ] 。既存のランタイムを仮想スレッドで改修した例としては、JavaのProject Loomがあります[ 13 ]。仮想スレッド用に設計された新しい言語の例としては、Goがあります[ 14 ]。
仮想スレッドは並列処理を提供するため、プログラマーはマルチスレッドプログラミングと同期処理に関する高度なスキルを身につける必要がある。
ブロックされた仮想スレッドは、現在占有しているOSスレッドをブロックしてしまうため、実行時にはブロッキングシステムコールを処理するために多大な労力を費やす必要があります。通常、仮想スレッドのブロッキングコールを実行するために、予備のOSスレッドプールからスレッドが使用され、最初に実行されていたOSスレッドがブロックされないようにします。
仮想スレッドスタックの管理には、リンカでの注意深い処理と、追加のスタック領域要件に関する短期的な予測が必要です。
仮想スレッドは、シングルトンの入出力アクティビティをシリアル化するために使用され、ブラウザを拡張する開発者が利用できます。仮想スレッドが実行されている間は、別のOSスレッドにジャンプすることができます。[ 15 ]
Go言語のゴルーチンは、2014年のGo 1.4でプリエンプティブになり、仮想スレッドの代表的な応用例となっている。
Java は 2023 年に Java 21 で主にプリエンプティブな仮想スレッドを導入しましたが、同期ブロックやネイティブ呼び出しを使用する仮想スレッドで実行されるコードは、キャリア OS スレッドに固定されるという制限がありました。[ 16 ]この制限は Java 24 で修正されました。[ 17 ]
Intel [ 18 ]は2007年に、Intelコンパイラ固有の最適化技術を仮想スレッドと呼んだ。