例を使用したJavaスレッド状態の紹介–スレッドのライフサイクル
公開: 2019-01-11
スレッドの状態
次の図は、Javaスレッドがその存続期間中の任意の時点にある可能性があるさまざまな状態と、どのメソッド呼び出しが別の状態への遷移を引き起こすかを示しています。 この図は完全な有限状態図ではなく、スレッドの寿命のより興味深く一般的な側面の概要です。
以下の質問のいずれかがある場合、あなたは正しい場所にいます:
- Javaでのスレッドのライフサイクル
- Javaのスレッドのライフサイクルと状態
- Javaスレッドの状態を理解する
このページの残りの部分では、 Thread's life cycle
についてその状態の観点から説明します。

新しいスレッド
次のステートメントは、新しいスレッドを作成しますが、それを開始しないため、図で「新しいスレッド」というラベルの付いた状態のままになります。
1 |
Thread myThread = new MyThreadClass ( ) ; |
スレッドがNew Thread
状態にあるとき、それは単に空のThreadオブジェクトです。 システムリソースはまだ割り当てられていません。 したがって、スレッドがこの状態にあるときは、スレッドを開始または停止することしかできません。 スレッドがこの状態にあるときにstart()
またはstop()
)以外の他のメソッドを呼び出すことは意味がなく、IllegalThreadStateExceptionが発生します。
実行可能
ここで、次の2行のコードについて考えてみます。
1 2 |
Thread myThread = new MyThreadClass ( ) ; myThread . start ( ) ; |
start()
メソッドは、スレッドの実行に必要なシステムリソースを作成し、スレッドの実行をスケジュールして、スレッドのrun()
メソッドを呼び出します。 この時点で、スレッドは「実行可能」状態になっています。 この状態では、スレッドが実際には実行されていない可能性があるため、この状態は「実行中」ではなく「実行可能」と呼ばれます。 多くのコンピューターには単一のプロセッサーが搭載されているため、すべての「実行可能」スレッドを同時に実行することはできません。
したがって、Javaランタイムシステムは、すべての「実行可能」スレッド間でプロセッサを共有するスケジューリングスキームを実装する必要があります。 ただし、ほとんどの場合、「実行可能」状態は単に「実行中」と考えることができます。 スレッドが実行中の場合(「実行可能」であり、現在のスレッドである場合)、 run()
内の命令は順番に実行されます。
実行不可
次の4つのイベントのいずれかが発生すると、スレッドはNot Runnable
状態になります。
- 誰かがその
suspend()
メソッドを呼び出します - 誰かがその
sleep()
メソッドを呼び出します - スレッドは
wait()
メソッドを使用して条件変数を待機します - スレッドがI / Oをブロックしています。
たとえば、このコードスニペットの太線は
1 2 3 4 5 6 |
Thread myThread = new MyThreadClass ( ) ; myThread . start ( ) ; try { myThread . sleep ( 10000 ) ; } catch ( InterruptedException e ) { } |
myThread
を10秒間(10,000ミリ秒)スリープ状態にします。 この10秒間、プロセッサが使用可能になったとしても、 myThread
は実行されませんでした。 10秒が経過すると、 myThread
は再び「実行可能」になり、プロセッサが使用可能になるとmyThread
が実行されます。
上記の「実行不可」状態への「入口」ごとに、スレッドを「実行可能」状態に戻す特定の明確なエスケープルートがあります。 脱出ルートは、対応する「入口」に対してのみ機能します。 たとえば、スレッドがスリープ状態になっている場合、スレッドが再び「実行可能」になるには、指定されたミリ秒数が経過する必要があります。 スリープ状態のスレッドでresume()
を呼び出しても効果はありません。
以下は、「実行不可」状態へのすべての入口の脱出ルートを示しています。
- スレッドがスリープ状態になっている場合は、指定されたミリ秒数が経過する必要があります。
- スレッドが一時停止されている場合は、誰かがその
resume()
メソッドを呼び出す必要があります。 - スレッドが条件変数を待機している場合、変数を所有するオブジェクトは、notify
notify()
またはnotifyAll()
のいずれかを呼び出して変数を放棄する必要があります。 - スレッドがI / Oでブロックされている場合は、指定されたI / Oコマンドを完了する必要があります。

死
スレッドは2つの方法で死ぬ可能性があります:自然な原因によるか、または殺される(停止される)ことによるかのいずれかです。 run()
メソッドが正常に終了すると、スレッドは自然に終了します。 たとえば、このメソッドのwhile
ループは有限ループであり、100回繰り返されてから終了します。

1 2 3 4 5 6 7 |
public void run ( ) { int i = 0 ; while ( i < 100 ) { i ++ ; System . out . println ( "i = " + i ) ; } } |
このrun()
メソッドを持つスレッドは、ループとrun()
メソッドの完了後に自然に終了します。
stop()
メソッドを呼び出すことにより、いつでもスレッドを強制終了できます。 このコードスニペット。
1 2 3 4 5 6 7 |
Thread myThread = new MyThreadClass ( ) ; myThread . start ( ) ; try { Thread . currentThread ( ) . sleep ( 10000 ) ; } catch ( InterruptedException e ) { } myThread . stop ( ) ; |
myThread
を作成して開始し、現在のスレッドを10秒間スリープ状態にします。 現在のスレッドがウェイクアップすると、コードセグメントの太線でmyThread
が強制終了されます。
stop()
メソッドは、スレッドにThreadDeathオブジェクトをスローして、それを強制終了します。 したがって、スレッドがこの方法で強制終了されると、非同期で停止します。 スレッドは、実際にThreadDeath例外を受け取ったときに停止します。
IllegalThreadStateException
スレッドでメソッドを呼び出し、そのスレッドの状態でそのメソッド呼び出しが許可されていない場合、ランタイムシステムはIllegalThreadStateExceptionをスローします。 たとえば、「実行可能」ではないスレッドでsuspend()
を呼び出すと、IllegalThreadStateExceptionがスローされます。
このレッスンのこれまでのスレッドのさまざまな例に示されているように、例外をスローできるスレッドメソッドを呼び出すときは、例外をキャッチして処理するか、呼び出し元のメソッドがキャッチされない例外をスローすることを宣言する必要があります。
isAlive()メソッド
そして、スレッドの状態についての最後の言葉です。Threadクラスのプログラミングインターフェイスには、 isAlive()
というメソッドが含まれています。 isAlive()
は、スレッドが開始され、停止されていない場合にtrueを返します。 したがって、 isAlive()
メソッドがfalseを返す場合は、スレッドが「新しいスレッド」または「デッド」のいずれかであることがわかります。
isAlive()
メソッドがtrueを返す場合、スレッドが「実行可能」または「実行不可」のいずれかであることがわかります。 「新しいスレッド」と「デッド」スレッドを区別することはできません。 また、「実行可能」スレッドと「実行不可能」スレッドを区別することもできません。
複雑なスレッドの例を見ていると、ネット上でこの本当に素晴らしいチュートリアルが見つかりました。 誰もがこれを注意深く読むべきです。