インタビューでは、wait、notify、notifyAll の使用は同期コード ブロック、つまり synchronized で使用する必要があるとよく言われます。
Java では、synchronized キーワードは、スレッドの相互排他的アクセスを実装するために使用されます。つまり、 synchronized キーワードでラップされたコード ブロックまたはメソッドを実行できるのは、一度に 1 つのスレッドだけです。これにより、共有リソースに対する操作がスレッドセーフであることが保証されます。
wait() メソッドは、他のスレッドが同じオブジェクトの Notice() メソッドまたは NotifyAll() メソッドを呼び出してウェイクアップするまで、現在のスレッドを待機状態にするために使用されます。スレッドが wait() メソッドを呼び出すと、現在保持されているロックが解放され、他のスレッドがクリティカル セクションに入り、関連する操作を実行できるようになります。
Notice() メソッドは、待機中のスレッドを起動するために使用されます。複数のスレッドが待機している場合、そのうちの 1 つのスレッドしか起動できず、どのスレッドを起動するかは不明です。NoticeAll() メソッドは、待機中のすべてのスレッドを起動し、ロックを再び競合させます。
ここで、wait()、notify()、notifyAll() を synchronized で使用する必要がある理由を見てみましょう。
1. スレッドの安全性
wait()、notify()、およびnotifyAll()メソッドは、現在のスレッドがオブジェクトのモニター・ロックを確実に取得している(つまり、同期によってロックを取得している)ことを確認するために、同期ブロックまたは同期メソッドで呼び出す必要があります。メソッドが呼び出され、ロックの解放やウェイクアップなどの操作が実行されます。
2. モニターロックの解除と復帰
スレッドがwait() メソッドを呼び出すと、現在保持されているモニター ロックが解放され、他のスレッドがロックを取得して関連する操作を実行できるようになります。Notice() メソッドまたは NotifyAll() メソッドが呼び出されると、ウェイクアップされたスレッドはロックを取得するために再競合し、ロックが取得されると、実行を継続できます。
3. スレッド間通信
wait()、notify()、notifyAll() メソッドは、スレッド間通信を実現するための鍵となります。wait() メソッドを呼び出すことによって、スレッドは特定の条件が満たされるのを待つことができ、notify() または NoticeAll() メソッドを通じて、スレッドは条件が満たされたことを待機中の他のスレッドに通知することができます。実行を続けます。
要約すると、スレッドの安全性を確保し、モニター ロックを適切に解放および復元し、効率的なスレッド間通信を可能にするために、wait()、notify()、およびnotifyAll() メソッドを synchronized キーワードとともに使用する必要があります。