wait()を実行した後、他のスレッドから通知を受け取らない場合、スレッドはどのくらい待機しますか?
以下の例では、メインスレッドは子スレッドから通知を受け取っていないため、永久に待機する必要があります。しかし、メインスレッドは実行されており、以下の例の出力は次のとおりです。
c
l
total: 19900
メインスレッドが実行されるのはなぜですか?
public class ThreadX extends Thread {
static int total = 0;
public void run() {
synchronized (this) {
for (int i = 0; i < 200; i++) {
total = total + i;
}
System.out.println("c");
}
}
public static void main(String[] args) throws InterruptedException {
ThreadX t = new ThreadX();
t.start();
synchronized (t) {
t.wait();
System.out.println("l");
}
System.out.println("total: " + total);
}
}
回答
10 akuzminykh
質問への回答-本文
チェックアウトThread#join(long):
[...]スレッドが終了すると、
this.notifyAll
メソッドが呼び出されます。[...]
Thread#join()
その関数を0
、で呼び出すことに注意してください。これは永遠を意味します。
[...]タイムアウト0は、永久に待機することを意味します。
したがって、あなたの場合、ここt
ではnotifyAll
終了時に呼び出すだけで、待機しているメインスレッドに通知しt
ます。
この直感的でない動作が、ドキュメントに次のように書かれている理由です。
アプリケーションが使用しないことをお勧めします
wait
、notify
またはnotifyAll
上Thread
のインスタンス。
質問への回答-タイトル
チェックアウトObject#wait(またはJLS(17.2.1。待機)):
スレッドは、通知、中断、またはタイムアウトすることなく、いわゆるスプリアスウェイクアップでウェイクアップできます。これが実際に発生することはめったにありませんが、アプリケーションは、スレッドをウェイクアップさせるはずの条件をテストし、条件が満たされない場合は待機し続けることによって、これを防ぐ必要があります。
したがって、Javaのスレッドはいつでもウェイクアップできます。偽のウェイクアップはほとんど発生しませんが、発生する可能性があります。