В следующем коде два потребительских потока запускаются и становятся ожидающими. Поток продюсера запускается (очень вероятно) после этого и вызывает 'notify'. Все потоки используют производителя в качестве монитора.
Thread producer = new Thread() {
@Override
public void run() {
synchronized (this) {
System.out.printf("notify at %d %n", getId());
notify();
}
}
};
Runnable consumer = () -> {
try {
synchronized (producer) {
long id = Thread.currentThread().getId();
System.out.printf("wait at %d %n", id);
producer.wait();
System.out.printf("awakened: %d %n", id);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Stream.generate( () -> consumer )
.limit(2)
.map(Thread::new)
.forEach(Thread::start);
Thread.sleep(3000); // consumer threads are (likely) waiting
producer.start();
От javado c для Object.notify :
Просыпается один ожидающий поток на мониторе этого объекта.
Код выдает такой (или аналогичный) вывод:
wait at 13
wait at 14
notify at 12
awakened: 13
awakened: 14
Дело в том, что пробуждаются оба потребительских потока, а не только один из них. Почему?
Скомпилировано и протестировано с помощью среды выполнения OpenJDK AdoptOpenJDK (сборка 11.0.5 + 10) в Windows 10, 64-бит.
Заранее спасибо!