モジュール java.base
パッケージ java.lang

クラスThread

java.lang.Object
java.lang.Thread
すべての実装されたインタフェース:
Runnable
直系の既知のサブクラス:
ForkJoinWorkerThread

public class Thread extends Object implements Runnable
スレッドとは、プログラム内での実行スレッドのことです。 Java仮想マシンを使用すると、1つのアプリケーションで複数のスレッドの実行を同時に実行できます。

Threadは、スレッドを作成するためのコンストラクタおよびThread.Builderを定義します。 「開始中」は、スレッドがrunメソッドを実行するようにスケジュールします。 新しく起動されたスレッドは、起動の原因となったスレッドと同時に実行されます。

スレッド「終了」は、そのrunメソッドが正常に完了した場合、またはそのrunメソッドが突然完了し、適切な「捕捉されない例外ハンドラ」が正常に完了または突然完了した場合です。 実行するコードが残っていないため、スレッドは実行を完了しました。 joinメソッドを使用すると、スレッドが終了するのを待機できます。

スレッドには、一意のidentifierおよびnameがあります。 識別子は、Threadの作成時に生成され、変更できません。 スレッド名は、スレッドの作成時に指定することも、後で「変更済」にすることもできます。

スレッドはThreadLocal変数をサポートします。 スレッドに対してローカルな変数です。つまり、スレッドは、他のスレッドによって設定された値とは無関係な値に設定された変数のコピーを持つことができます。 Threadでは、親Threadからスレッド作成時に継承されるスレッド・ローカル変数であるInheritableThreadLocal変数もサポートされます。 Threadは、スレッドcontext-class-loaderの特別な継承可能スレッド・ローカルをサポートします。

プラットフォーム・スレッド

Threadでは、通常、オペレーティング・システムによってスケジュールされたカーネル・スレッドに1:1でマップされる「プラットフォーム・スレッド」の作成がサポートされています。 通常、プラットフォーム・スレッドには、オペレーティング・システムによって保守される大きなスタックおよびその他のリソースがあります。 プラットフォームのスレッドは、すべてのタイプのタスクの実行に適していますが、リソースは限られています。

プラットフォーム・スレッドは、デフォルトで自動的に生成されたスレッド名を取得します。

プラットフォーム・スレッドは、「デーモン」または「非デーモン」スレッドに指定されています。 Java仮想マシンが起動すると、通常、非デーモン・スレッド(通常はアプリケーションのmainメソッドをコールするスレッド)が1つあります。 「停止シーケンス」は、起動されたすべての非デーモン・スレッドが終了すると開始します。 未起動のデーモン以外のスレッドは、停止シーケンスの開始を妨げません。

デーモンのステータスに加えて、プラットフォーム・スレッドには「スレッドの優先順位」があり、「スレッド・グループ」のメンバーです。

仮想スレッド

Threadでは、「仮想スレッド」の作成もサポートされています。 仮想スレッドは通常、オペレーティング・システムではなくJavaランタイムによってスケジュールされる「ユーザー・モード・スレッド」です。 仮想スレッドでは通常、必要なリソースはほとんどなく、単一のJava仮想マシンで数百万の仮想スレッドがサポートされる場合があります。 仮想スレッドは、ほとんどの時間をブロックしてI/O演算の完了を待機するタスクの実行に適しています。 仮想スレッドは、長時間実行するCPU集中型の演算を目的としていません。

仮想スレッドは通常、「キャリア・スレッド」として使用される小さなプラットフォーム・スレッド・セットを使用します。 ロックおよびI/O演算は、ある仮想スレッドから別の仮想スレッドにキャリア・スレッドを再スケジュールできる演算の例です。 仮想スレッドで実行されているコードは、基になるキャリア・スレッドを認識しません。 「現在のスレッド」への参照を取得するために使用されるcurrentThread()メソッドは、常に仮想スレッドのThreadオブジェクトを返します。

仮想スレッドにはデフォルトでスレッド名がありません。 スレッド名が設定されていない場合、getNameメソッドは空の文字列を返します。

仮想スレッドはデーモン・スレッドであるため、「停止シーケンス」の開始を妨げません。 仮想スレッドには、変更できない固定の「スレッドの優先順位」があります。

スレッドの作成および開始

Threadでは、プラットフォーム・スレッドを作成するためのパブリック・コンストラクタと、実行するスレッドをスケジュールするstartメソッドを定義します。 Threadはカスタマイズやその他の高度な理由で拡張できますが、ほとんどのアプリケーションではこれを行う必要はほとんどありません。

Threadは、プラットフォームと仮想スレッドの両方を作成および開始するためのThread.Builder APIを定義します。 次に、ビルダーを使用する例を示します:

  Runnable runnable = ...

  // Start a daemon thread to run a task
  Thread thread = Thread.ofPlatform().daemon().start(runnable);

  // Create an unstarted thread with name "duke", its start() method
  // must be invoked to schedule it to execute.
  Thread thread = Thread.ofPlatform().name("duke").unstarted(runnable);

  // A ThreadFactory that creates daemon threads named "worker-0", "worker-1", ...
  ThreadFactory factory = Thread.ofPlatform().daemon().name("worker-", 0).factory();

  // Start a virtual thread to run a task
  Thread thread = Thread.ofVirtual().start(runnable);

  // A ThreadFactory that creates virtual threads
  ThreadFactory factory = Thread.ofVirtual().factory();

スレッド作成時の継承

Threadは、子Threadの作成時に親スレッド値からinheritable-thread-local変数(コンテキスト・クラス・ローダーを含む)の初期値を継承します。 5パラメータconstructorを使用して、構成スレッドから初期値を継承しないスレッドを作成できます。 Thread.Builderを使用する場合、inheritInheritableThreadLocalsメソッドを使用して初期値を継承するかどうかを選択できます。

プラットフォーム・スレッドは、デーモンのステータス、スレッド優先度、および(またはセキュリティ・マネージャによって選択されていない)が指定されていない場合、スレッド・グループを継承します。

プラットフォーム・スレッド「取得」を作成して、「特権アクション」を実行するコードを実行するときに新しいスレッドの「権限」を制限します。 取得されたコール元コンテキストは新しいスレッド「継承されたAccessControlContext」です。 仮想スレッドを作成しても、呼び出し元のコンテキストは取得されません。特権アクションを実行するコードを実行するとき、仮想スレッドにはアクセス権がありません。

特に指定しないかぎり、このクラスのコンストラクタまたはメソッドにnull引数を渡すと、NullPointerExceptionがスローされます。

実装上のノート:
JDKリファレンス実装では、仮想スレッド・スケジューラは次のシステム・プロパティで構成できます:
システム・プロパティ
システム・プロパティ 説明
jdk.virtualThreadScheduler.parallelism 仮想スレッドのスケジューリングに使用できるプラットフォーム・スレッドの数。 デフォルトで使用可能なプロセッサの数です。
jdk.virtualThreadScheduler.maxPoolSize スケジューラで使用可能なプラットフォーム・スレッドの最大数。 デフォルトは256です。
導入されたバージョン:
1.0