SOコンセンサスとほぼすべてのJavaインターネット上のスレッド状態図、特にスレッド状態遷移に関してfromWAITING
notify()
またはnotifyAll()
が呼び出された後...
したがって、SO=のコンセンサスは:notify()
またはnotifyAll()
を呼び出した後、スレッドがWAITING
からBLOCKED
に移行します下の図は、この遷移を緑色で示しています。
なぜほとんどの ウェブ上の状態図 は、WAITING
ではなくRUNNABLE
からBLOCKED
への遷移を示しているのですか?赤の説明は、誤った遷移を示しています。私は何かを逃していますか?
スレッドをWAITINGからRUNNABLEに移行するnotify
呼び出しを示す図はすべて間違っています(または不明なショートカットを使用しています)。スレッドがnotify
から(または偽のウェイクアップからさえ)起こされると、待機しているオブジェクトのモニターを再度ロックする必要があります。これは BLOCKED
状態です。
モニターロックを待機してブロックされたスレッドのスレッド状態。ブロック状態のスレッドは、モニターロックが同期ブロック/メソッドに入るか、_
Object.wait
_を呼び出した後に同期ブロック/メソッドに再び入るのを待っています。
これは Object#notify()
のjavadocで説明されています:
目覚めたスレッドは、現在のスレッドがこのオブジェクトのロックを放棄するまで続行できません。
および Object#wait()
スレッドは、モニターの所有権を再取得できるまで待機し、実行を再開します。
スレッドは[〜#〜] waiting [〜#〜]状態になります[〜#〜] block [〜#〜]状態になります。通知して[〜#〜] runnable [〜#〜]になります。
同じことが[〜#〜] timedwaiting [〜#〜]にも当てはまります。モニターは[〜#〜] block [〜#〜]状態になります。指定された時間が経過しても、他のいくつかのスレッド。(ダイアグラムを修正する必要があります)
私は最近問題に焦点を合わせています。
oracleドキュメント Thread.State によると、LockSupport.park()を使用して現在のスレッドを「WAITING」または「TIMED_WAITING」状態にすることができます。
したがって、 LockSupport.unpark() を試行すると、指定されたスレッドは「WAITING」/「TIMED_WAITING」から「RUNNABLE」に戻ります。 (「BLOCKED」状態になるかどうかはわかりません)