notify/wait (пессимистическая блокировка) – условие этого задания, то есть требуется реализовать уже существую BlockingQueue.Эти методы вместе с
synchronized – самый низкий уровень пессимистических блокировок в Java, использующийся внутри реализации примитивов синхронизации. Еще с Java 5 в непосредственном использовании этих методов нет необходимости, но теоретические знания всё еще часто спрашивают на интервью.Чтобы вызывать эти методы у объекта, необходимо чтобы был захвачен его монитор (т.е. нужно быть внутри synchronized-блока на этом объекте). В противном случае будет выброшено
IllegalMonitorStateException. Так что для полного ответа нужно понимать, как работает monitor lock (блок synchronized).Вызов
wait тормозит текущий поток на ожидание на этом объекте и отпускает его монитор. Исполнение продолжится, когда другой поток вызовет notify и отпустит блокировку монитора. Если на объекте ожидают несколько потоков, notify разбудит один случайный, notifyAll - все сразу.В теории, ожидание
wait может быть прервано без вызова notify, по желанию JVM (spurious wakeup). На практике это бывает крайне редко, но нужно страховаться и после вызова wait добавлять дополнительную проверку условия завершения ожидания.Еще два нештатных случая завершения
wait – прерывание потока извне и таймаут ожидания. В случае прерывания выбрасывается InterruptedException. Для таймаута нужно указать время ожидания параметрами метода wait. Значение 0 проигнорируется.Различные проблемы реализации блокировок рассмотрены в Java Concurrency in Practice 14.1.3, 14.2. Для желающих разобраться, как блокировки работают в кишках JVM, написана статья на хабре.