Я мог бы только раскалывать волосы ;-) Возможно, было бы не совсем правильно думать о том, что потоки переводятся из состояния «ожидания» в состояние «работы» в notifyAll; по крайней мере, без предостережения, что первое, что делает уведомленный поток, это повторно захватывает блокировку монитора. А поскольку его может захватить только один из числа уведомленных потоков, остальные будут заблокированы . BLOCKED ( Thread.State.Blocked ) - состояние потока. Но блокировка отличается от ожидания , потому что заблокированному потоку не нужен еще один сигнал notify () для возобновления. [ Хорошо, я знаю о ложных пробуждениях, но, возможно, обратное также может быть верно для некоторых реализаций JVM - пропущенное уведомление? ]
public class HellBoy {
public static class MyThread extends Thread {
static final public Object sharedLock = new Object();
public void run() {
synchronized (sharedLock) {
System.out.println("Gonna wait...");
try {
sharedLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Woken up but sleeping with the lock");
try {
Thread.sleep(2500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("exiting and unlocking");
}
}
}
public static void main(String[] args) throws Exception {
new MyThread().start();
new MyThread().start();
new MyThread().start();
new MyThread().start();
Thread.sleep(200);
synchronized (MyThread.sharedLock) {
MyThread.sharedLock.notifyAll();
}
}
}