人間が生まれ、老い、病気になり、死ぬのと同じように、スレッドも開始 (待機)、実行、ハング、停止という 4 つの異なる状態を経る必要があります。これら 4 つの状態は、Thread クラスのメソッドを通じて制御できます。 Thread クラスのこれら 4 つの状態に関連するメソッドを以下に示します。
// スレッドを一時停止してウェイクアップします
public voidresume( ); // 使用は推奨されません。
public void stop( ); // 使用は推奨されません。
public static void sleep(ロングミリス);
public static void sleep(long millis, int nanos);
// スレッドを終了する
public void stop( ); // 使用は推奨されません。
パブリックボイド割り込み();
// スレッドのステータスを取得する
パブリックブール値 isAlive( );
public boolean isInterrupted( );
public static boolean中断();
// 結合メソッド
public void join( ) は InterruptedException をスローします。
スレッドは確立直後に run メソッド内のコードを実行せず、待機状態になります。スレッドが待機状態にある場合、Thread クラスのメソッドを通じて、スレッドの優先順位 (setPriority)、スレッド名 (setName)、スレッド タイプ (setDaemon) などのスレッドのさまざまな属性を設定できます。
start メソッドが呼び出されると、スレッドは run メソッド内のコードの実行を開始します。スレッドは実行状態になります。 Thread クラスの isAlive メソッドを使用して、スレッドが実行されているかどうかを確認できます。スレッドが実行状態にある場合、isAlive は true を返します。isAlive が false を返す場合、スレッドは待機状態または停止状態にある可能性があります。次のコードは、スレッドの作成、実行、停止の 3 つの状態間の切り替えを示し、対応する isAlive 戻り値を出力します。
パブリック クラス LifeCycle はスレッドを拡張します
{
public void run()
{
int n = 0;
while ((++n) < 1000);
}
public static void main(String[] args) が例外をスローする
{
LifeCycle thread1 = new LifeCycle();
System.out.println("isAlive: " + thread1.isAlive());
thread1.start();
System.out.println("isAlive: " + thread1.isAlive());
thread1.join(); // スレッド thread1 が終了するまで待ってから実行を続行します
System.out.println("スレッド 1 が終了しました!");
System.out.println("isAlive: " + thread1.isAlive());
}
}
上記のコードを実行した結果:
スレッドが run メソッドの実行を開始すると、run メソッドが完了するまでスレッドは終了しません。ただし、スレッドの実行中に、スレッドの実行を一時的に停止するために使用できる方法が 2 つあります。これら 2 つのメソッドは、suspend と sleep です。suspend を使用してスレッドを一時停止した後、resume メソッドを使用してスレッドをウェイクアップできます。 sleep を使用してスレッドをスリープ状態にした後、スレッドは設定された時間が経過した後にのみ準備完了状態になることができます (スレッドのスリープ終了後、スレッドはすぐには実行されない場合がありますが、システムがスケジュールするのを待って準備完了状態になるだけです)。 。
サスペンドとレジュームはスレッドを簡単にサスペンドしたりウェイクアップしたりできますが、これら 2 つのメソッドを使用すると、予期せぬ事態が発生する可能性があります。そのため、これら 2 つのメソッドは非推奨 (抗議) としてマークされており、これらの 2 つのメソッドは将来の JDK で削除される可能性があることを示しています。バージョンが異なるため、これら 2 つの方法を使用してスレッドを操作しないようにしてください。次のコードは、sleep、suspend、resume メソッドの使用を示しています。
パブリッククラスMyThreadはThreadを拡張します
{
クラス SleepThread は Thread を拡張します
{
public void run()
{
試す
{
睡眠(2000);
}
catch (例外 e)
{
}
}
}
public void run()
{
その間(真)
System.out.println(new java.util.Date().getTime());
}
public static void main(String[] args) が例外をスローする
{
MyThread スレッド = new MyThread();
スリープスレッド sleepThread = thread.new SleepThread();
sleepThread.start(); // スレッドの実行を開始します。
sleepThread.join(); // スレッド sleepThread を 2 秒遅延します。
thread.start();
ブール値フラグ = false;
その間(真)
{
sleep(5000); // メインスレッドを 5 秒遅延します。
フラグ = !フラグ;
もし(フラグ)
スレッド.サスペンド();
それ以外
thread.resume();
}
}
}
sleep メソッドを使用する際の注意点は次の 2 つです。
1. sleep メソッドには 2 つのオーバーロード形式があります。オーバーロード形式の 1 つは、ミリ秒だけでなくナノ秒も設定できます (1,000,000 ナノ秒は 1 ミリ秒に相当します)。ただし、ほとんどのオペレーティング システム プラットフォームの Java 仮想マシンはナノ秒まで正確ではないため、スリープにナノ秒が設定されている場合、Java 仮想マシンはこの値に最も近いミリ秒を取得します。
2. sleep メソッドを使用する場合は、throws または try{…}catch{…} を使用する必要があります。run メソッドでは throws を使用できないため、スレッドが sleep している場合は try{…}catch{…} のみを使用できます。割り込みメソッドを使用してスレッドを中断すると、InterruptedException がスローされます (このメソッドについては 2.3.3 で説明します)。スリープ メソッドは次のように定義されます。
スレッドを終了するには 3 つの方法があります。
1. 終了フラグを使用して、スレッドを正常に終了します。つまり、run メソッドが完了するとスレッドが終了します。
2. stop メソッドを使用してスレッドを強制的に終了します (サスペンドや再開と同様に停止によっても予期しない結果が生じる可能性があるため、この方法は推奨されません)。
3. スレッドを中断するには、interrupt メソッドを使用します。
1. 終了フラグを使用してスレッドを終了します。
run メソッドが実行されると、スレッドは終了します。ただし、run メソッドが終了しない場合があります。たとえば、スレッドはサーバー プログラムでクライアントの要求や、周期的な処理を必要とするその他のタスクを監視するために使用されます。この場合、これらのタスクは通常、while ループなどのループ内に配置されます。ループを永久に実行したい場合は、while(true){...} を使用して処理できます。ただし、特定の条件で while ループを終了させたい場合、最も直接的な方法は、ブール型フラグを設定し、このフラグを true または false に設定して while ループを終了するかどうかを制御することです。終了フラグを使用してスレッドを終了する例を以下に示します。
パブリッククラス ThreadFlag は Thread を拡張します
{
public volatile boolean exit = false;
public void run()
{
その間 (!終了);
}
public static void main(String[] args) が例外をスローする
{
ThreadFlag スレッド = new ThreadFlag();
thread.start();
sleep(5000); //メインスレッドは 5 秒遅延します。
thread.exit = true; // スレッド thread を終了します。
thread.join();
System.out.println("スレッドが終了しました!");
}
}
2. stop メソッドを使用してスレッドを終了します。
stop メソッドを使用して、実行中または一時停止中のスレッドを強制的に終了します。次のコードを使用してスレッドを終了できます。
3. 割り込みメソッドを使用してスレッドを終了します。
割り込みメソッドを使用してスレッドを終了する場合は、次の 2 つの状況に分けられます。
(1) スリープメソッドを使用するなど、スレッドがブロック状態になっている。
(2) while(!isInterrupted()){...} を使用して、スレッドが中断されているかどうかを判断します。
割り込みメソッドを使用する最初のケースでは、スリープ メソッドは InterruptedException 例外をスローしますが、2 番目のケースではスレッドが直接終了します。以下のコードは、最初のケースでの割り込みメソッドの使用を示しています。
パブリッククラス ThreadInterrupt は Thread を拡張します
{
public void run()
{
試す
{
sleep(50000); // 50 秒遅延します。
}
catch (InterruptedException e)
{
System.out.println(e.getMessage());
}
}
public static void main(String[] args) が例外をスローする
{
スレッド thread = new ThreadInterrupt();
thread.start();
System.out.println("スレッドを中断するには、50 秒以内に任意のキーを押してください!");
System.in.read();
thread.interrupt();
thread.join();
System.out.println("スレッドは終了しました!");
}
}
睡眠が中断された
スレッドは終了しました!
注: Thread クラスには、スレッドが割り込みメソッドによって終了されたかどうかを判断するメソッドが 2 つあります。 1 つは静的メソッドの interrupted() で、もう 1 つは非静的メソッド isInterrupted() です。これら 2 つのメソッドの違いは、interrupted は現在のスレッドが中断されているかどうかを判断するために使用されるのに対し、isInterrupted は現在のスレッドが中断されているかどうかを判断するために使用できることです。他のスレッドは中断されます。したがって、while (!isInterrupted()) は while (!Thread.interrupted()) に置き換えることもできます。