wait() と notify() が正確にどのように機能するかを知る必要がありますか? wait() と notify() をそのまま使用しても、その動作を達成できませんでした。代わりに、待機に while() ループを使用すると、正しく動作します。どうですか?単純に wait() と notify() だけを使用できないのはなぜですか?
3 に答える
wait() と notify() は、スレッドを使用して一時停止し、中断したところから再開するときに、同期ブロックで使用されます。
Wait はすぐにロックを解除しますが、Nofity は終了ブラケットが検出された場合にのみロックを解除します。
このサンプル例も参照できます。
public class MyThread implements Runnable {
public synchronized void waitTest() {
System.out.println("Before Wait");
wait();
System.out.println("After Wait");
}
public synchronized void notifyTest() {
System.out.println("Before Notify");
notify();
System.out.println("After Notify");
}
}
public class Test {
public static void main(String[] args) {
Thread t = new Thread(new MyThread());
t.start();
}
}
wait - notify関数のドキュメントを読みましたか?
とにかく、待機通知メカニズムを実現する最善の方法として、次のようなものを使用します (この Web サイトに基づく):
public class WaitNotifier {
private final Object monitoredObject = new Object();
private boolean wasSignalled = false;
/**
* waits till another thread has called doNotify (or if this thread was interrupted), or don't if was already
* notified before
*/
public void doWait() {
synchronized (monitoredObject) {
while (!wasSignalled) {
try {
monitoredObject.wait();
} catch (final InterruptedException e) {
break;
}
}
wasSignalled = false;
}
}
/**
* notifies the waiting thread . will notify it even if it's not waiting yet
*/
public void doNotify() {
synchronized (monitoredObject) {
wasSignalled = true;
monitoredObject.notify();
}
}
}
このクラスの各インスタンスは一度だけ使用する必要があることに注意してください。複数回使用する必要がある場合は、変更することをお勧めします。
while ループで機能し、なしでは機能しない理由を尋ねていると思います。答えは、プログラムがwait()を呼び出すと、オペレーティング システムがスレッドを一時停止して別のスレッドをアクティブ化 (開始) し、いわゆるコンテキスト スイッチが発生することです。OS がスレッドを一時停止すると、「メタデータ」を保存する必要があります。後でそのスレッドを再開できるようにするためのスレッドについて、PC レジスターはあなたの質問に答えるものです。スレッドはそれを使用して、OS が彼を中断したときにどの命令を実行しようとしていたかを理解し、その命令を続行します (この場合、Java プログラムでそれを見たい場合、次の命令は次の行になります) 「 Java Concurrency in Practice」に書かれているように、 wait()を呼び出します。
Every call to wait is implicitly associated with a specific condition predicate. When calling wait regarding a particular
condition predicate, the caller must already hold the lock associated with the condition queue, and that lock must also
guard the state variables from which the condition predicate is composed.
スレッドが中断されたメソッドに戻った後、いくつかの条件が満たされていない (満たされている必要がある)ためにスレッドが待機するため、その条件がまだ満たされているかどうかを再確認する必要があります。満たされていない場合、wait()が再度呼び出されます (while ループにあるため)。ここで知っておくべき重要なことは、
- PC(プログラムカウンター)のコンセプトと
- メソッドでwait()を呼び出すスレッドがメソッドを終了しないという事実->待機->再度再開->メソッドを再度呼び出し、代わりに待機->再開->ポイントから続行(命令/line) 中断された場所 (wait() と呼ばれる)