У вас есть так называемый пропущенный сигнал .Вы опрашиваете очередь, а затем ждете на мониторе (взяв блокировку).Потоки производителя добавляют события и затем вызывают notifyAll()
(взяв блокировку).Нет никакой связи между очередью / опросом событий и условным ожиданием / уведомлением.
Поэтому поток А может опрашивать, пока он пуст, а затем пытаться получить блокировку, а поток В добавляет элемент.и получает блокировку, уведомляя все ожидающие потоки, затем снимая блокировку.Затем поток A получает блокировку и ожидает ее, но сигнал был пропущен.
Поскольку вы используете блокировку исключительно для сигнализации, вы можете рассмотреть другой механизм, такой как многоразовая защелка, например, новый jdk7 * 1009 Дуга Ли.* Phaser , или просто используйте BlockingQueue
напрямую.
В качестве альтернативы у нас есть пара ReusableLatch , например BooleanLatch для одного потока чтения или PhasedLatch для многопартийной поддержки.