仮想スレッドとは
Java 21 の軽量なスレッドです。
「仮想スレッドとは」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。
仮想スレッドへようこそ
仮想スレッドはJava 21で最終的な機能として導入されました(JEP 444)。仮想スレッドは、オペレーティングシステムではなくJVMによって管理される軽量なスレッドです。
目的はシンプルです。リクエストごとに1スレッドという分かりやすいコードを書きながら、同時実行タスクを数百万規模まで拡張できるようにします。
従来の問題
従来のプラットフォームスレッドは、OSスレッドと1対1に対応します。各スレッドは約1メガバイトのスタックを消費し、作成にもコストがかかります。
そのため、一度に実行できるのは数千個に限られます。ブロッキングI/Oが発生すると、待機中はOSスレッド全体が占有されます。
仮想スレッドの違い
仮想スレッドはOSスレッドを所有しません。多数の仮想スレッドが、少数のキャリアプラットフォームスレッド上で多重化されます。
- 作成コストが低い(1ミリ秒あたり数千個)
- メモリ使用量が非常に少ない
- ブロッキングが発生すると仮想スレッドがパークされ、キャリアスレッドが解放される
マウントとアンマウント
仮想スレッドが実行されると、キャリアスレッドにマウントされます。ブロッキング処理に到達するとアンマウントされ、キャリアスレッドを解放して別の処理を進められるようにします。
このパークと再開は自動的に行われます。コードは通常のブロッキングコードと同じように記述できます。
最初の仮想スレッド
最も単純な例を見てみましょう。Thread.ofVirtual().start(...)で仮想スレッドを開始し、join()でその終了を待機します。
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread vt = Thread.ofVirtual().start(() ->
System.out.println("Hello from a virtual thread!"));
vt.join();
System.out.println("Main is done.");
}
}仮想スレッドであることを確認する
すべてのThreadにはisVirtual()が用意されています。これにより、コードがどの種類のスレッド上で実行されているかを確認できます。
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread vt = Thread.ofVirtual().start(() -> {
System.out.println("isVirtual: " + Thread.currentThread().isVirtual());
});
vt.join();
}
}多数のタスクにスケールする
仮想スレッドは低コストなので、数万個を起動してもまったく問題ありません。ここでは10,000個を起動します。
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
public static void main(String[] args) throws InterruptedException {
AtomicInteger counter = new AtomicInteger();
Thread[] threads = new Thread[10_000];
for (int i = 0; i < threads.length; i++) {
threads[i] = Thread.ofVirtual().start(counter::incrementAndGet);
}
for (Thread t : threads) t.join();
System.out.println("Completed: " + counter.get());
}
}仮想スレッドに名前を付ける
起動する前にビルダーを使うと、デバッグしやすいように仮想スレッドに名前を付けられます。
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread vt = Thread.ofVirtual()
.name("worker-1")
.start(() ->
System.out.println("Running on: " + Thread.currentThread().getName()));
vt.join();
}
}同じAPI、新しい実行エンジン
仮想スレッドは、すでにご存じのThread APIとまったく同じAPIを実装しています。引き続きstart、join、sleep、interruptを使用できます。
つまり、ThreadとRunnableを基盤とする既存のライブラリは、変更せずに動作します。
使いどき
仮想スレッドは、I/Oバウンドのワークロードで力を発揮します。Webサーバー、データベースへの呼び出し、リモート API リクエストなどです。
CPUバウンドの数値計算を速くするものではありません。その場合も、コア数による制約を受けます。
プールではありません
重要な考え方があります。仮想スレッドはプールしません。タスクごとに新しいものを作成し、タスクが終わったら終了させます。
プールは、高コストなリソースを再利用するために存在します。仮想スレッドは安価なので、プールするのはアンチパターンです。
理解度チェック
仮想スレッドについての理解度を確認しましょう。
復習
仮想スレッドとは何か、なぜ重要なのかを学びました。
- 軽量で JVM によって管理され、Java 21で正式採用された
- マウントとアンマウントによってキャリアスレッド上で多重化される
- 高い同時実行性が求められるI/Oバウンドの処理に最適
- 同じ
ThreadAPI を使用するが、プールではなくタスクごとに作成する
次は、仮想スレッドを作成するさまざまな方法を学びます。
よくある質問
「仮想スレッドとは」レッスンは無料ですか?
はい。「仮想スレッドとは」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。
「仮想スレッドとは」で何を学びますか?
Java 21 の軽量なスレッドです。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Java Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「仮想スレッドとは」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このJava Academyレッスンでコードを書いて実行できますか?
はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。