私はwait()がすべてのロックを解除すると思っていたのですが、この投稿を見つけました。
「同期メソッド内で wait を呼び出すことは、固有のロックを取得する簡単な方法です」
少し混乱しているので、説明してください。
詳細は、http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html を参照してください。
ベストアンサー1
「同期メソッド内で wait を呼び出すことは、固有のロックを取得する簡単な方法です」
この文は誤りであり、文書内のエラーです。
スレッドは、入る同期メソッド。同期メソッド内のスレッドはロックの所有者として設定され、実行可能状態。ロックされたメソッドに入ろうとするスレッドはブロックされました。
スレッドがwaitを呼び出すと、現在のオブジェクトロックが解放され(他のオブジェクトからのロックはすべて保持されます)、待っている州。
他のスレッドが同じオブジェクトに対してnotifyまたはnotifyAllを呼び出すと、最初のスレッドの状態がWAITINGからBLOCKEDに変わります。通知を受けたスレッドは自動的にロックを再取得したりRUNNABLEになったりすることはなく、実際には他のすべてのブロックされたスレッドとロックを争う必要があります。
WAITING 状態と BLOCKED 状態はどちらもスレッドの実行を防止しますが、これらは非常に異なります。
WAITING スレッドは、他のスレッドからの通知によって明示的に BLOCKED スレッドに変換される必要があります。
WAITING は直接 RUNNABLE に移行することはありません。
RUNNABLE スレッドがロックを解除すると (モニターを離れるか待機することによって)、BLOCKED スレッドの 1 つが自動的にその代わりになります。
まとめると、スレッドは同期メソッドに入るとき、または同期メソッドに再び入るときにロックを取得します。後待つこと。
public synchronized guardedJoy() {
// must get lock before entering here
while(!joy) {
try {
wait(); // releases lock here
// must regain the lock to reentering here
} catch (InterruptedException e) {}
}
System.out.println("Joy and efficiency have been achieved!");
}