スレッドの状態に関する多くのドキュメントを読みましたが、ブロックされた状態(同期前)と待機状態(呼び出しが待機している場合)の2つの異なる状態があると述べているものもあれば、状態が1つしかないことを示しているものもあります。さらに、wait()ごとにnotify()を呼び出す必要があると指示しているドキュメントもあります。そうしないと、モニターのロックが解除されていても、waiting()スレッドは実行の対象になりません。
4 に答える
synchronized
あなたの最後の文から、あなたはとwait()
/の違いを完全には理解していないことがわかりますnotify()
。
基本的に、モニターにはロックと状態があります。それはほぼ直交する概念です。
スレッドが
synchronized
ブロックに入ると、ロックを取得します。スレッドがそのブロックを離れると、ロックが解除されます。特定のモニターでロックできるのは1つのスレッドだけです。ロックを持っているスレッドがを呼び出すと
wait()
、ロックを解放し、その状態で待機を開始します。ロックを持っているスレッドがを呼び出すと、条件を待機しnotify()
ているスレッドの1つ(の場合はすべてのスレッドnotifyAll()
)が実行の対象になります(そして、通知スレッドがまだロックを持っているため、ロックの取得を待機し始めます)。
したがって、ロックの取得を待機すること(Thread.State.BLOCKED)とモニターの状態を待機すること(Thread.State.WAITING)は、異なる独立した状態です。
この動作は、クラスを見るとより明確になります。これは、ブロックLock
と同じ同期プリミティブsynchronized
(一部の拡張機能を含む)を実装しますが、ロックと条件を明確に区別します。
スレッドが
Object.wait
メソッドを呼び出すと、この取得されたモニターが解放され、WAITING
(またはTIMED_WAITING
、待機メソッドのタイムアウトバージョンを呼び出す場合は)状態になります。notify()
これで、スレッドが同じオブジェクトの呼び出しによって、または呼び出しによって通知されるnotifyAll()
と、スレッドの待機状態が終了し、スレッドは待機呼び出し時に取得したすべてのモニターを取り戻そうとし始めます。一度に、モニターを取り戻そうとしている(または初めて取得しようとしている)スレッドがいくつかある場合があります。複数のスレッドが特定のオブジェクトのモニターを取得しようとすると、(JVM
スケジューラーによって選択された)1つのスレッドのみにモニターが付与され、他のすべてのスレッドがBLOCKED
状態になります。
BLOCKEDとWAITINGの2つの異なる状態があります。
誰もあなたに通知(または中断)しない場合に永遠に待つことについての部分は真実です。
Javaの観点(Thread.State)では、BLOCKEDとWAITINGの2つの異なる状態があります。スレッドがオブジェクトで同期するとき、スレッドはBLOCKED状態になります。スレッドがwaitを実行した後、スレッドはWAITING状態になります。
Linuxプラットフォームでは、JavaスレッドはOSネイティブスレッドです。BLOCKED状態とWAITING状態の両方のOSスレッド状態は、割り込み可能なスリープです。psでチェックすると、BLOCKEDスレッドとWAITINGスレッドの両方の状態は「Sl+」です。