Если lockB
не защищает какое-либо состояние, в котором поток может захотеть ждать изменений или может потребоваться уведомить другой поток об изменениях, использование его в сочетании с wait
и notify
не имеет никакого смысла.
synchronized (B.lockB){
try {
B.lockB.wait();
Вы никогда не должны звонить wait
, пока не проверите, чтобы убедиться, что то, чего вы ждете, еще не произошло. Причина, по которой этот код находится внутри блока synchronized
, заключается именно в том, что вы можете выполнить эту проверку и ждать, если и только если вам нужно подождать.
synchronized (B.lockB){
B.lockB.notifyAll();
}
Это довольно сложно. Почему вы звоните lockB.notifyAll()
, если вы не изменили ничего, защищенного этой блокировкой, о которой вам нужно уведомить другие темы?
Похоже, вы не понимаете, как на самом деле работает семантика wait
/ notify
. Дело в том, что вам нужно только подождать, если что-то еще не произошло, и вы никогда не сможете быть уверены, что это уже произошло (потому что планировщики непредсказуемы) без удержания какой-либо блокировки. Но вам нужно снять блокировку, прежде чем ждать, создавая состояние гонки, если какой-то другой поток делает то, что вы ожидаете, после того, как вы сняли блокировку, но до того, как вы начали ждать. Функция wait
- это атомарная функция, которая снимает блокировку и ждет, когда что-то произойдет. Атомность избегает этого состояния гонки.
Однако у вас нет разблокированного замка, защищающего то, что вы ждете. Это разрушает логику функции атомной разблокировки и ожидания и приводит к коду, который всегда может зайти в тупик.