私は、wait() メソッドの特定の使用例に戸惑っています。
javadoc によると、待機は次のいずれかの条件が発生したときに終了する必要があります。
- 別のスレッドが notify または notifyAll を呼び出します (通知の詳細については javadoc を参照してください。ただし、これはこの質問には関係ありません)。
- 別のスレッドがこの (待機中の) スレッドに割り込む
- タイムアウトの期限が切れる (タイムアウト付きの待機バージョンを使用している場合)
待機しているオブジェクト自体がスレッドである場合、notify() が呼び出されていなくても、wait() が終了し、上記の条件のいずれも保持されないことがあります。しかし、Thread.run() メソッドが終了したときに発生します。この動作は理にかなっているかもしれませんが、Thread javadoc 内に文書化されるべきではありませんか? join() の動作と重複するため、非常に紛らわしいと思います。
これは私のテストコードです:
public static class WorkerThread extends Thread {
@Override public void run() {
try{
System.out.println("WT: waiting 4 seconds");
Thread.sleep(4000);
synchronized (this) {
notify();
}
System.out.println("WT: waiting for 4 seconds again");
Thread.sleep(4000);
System.out.println("WT: exiting");
} catch (InterruptedException ignore) {
ignore.printStackTrace();
}
}
}
public static void main (String [] args) throws InterruptedException {
WorkerThread w = new WorkerThread();
w.start();
synchronized(w) {
w.wait();
System.out.println("MT: The object has been notified by the thread!");
}
synchronized(w) {
w.wait(); //THIS FINISHES WITHOUT notify(), interrupt() OR TIMEOUT!
System.out.println("MT: The thread has been notified again!");
}
}