Может быть, это не делает то, о чем вы думали:
while (flag) {
...
}
То, что l oop будет не завершится всякий раз, когда flag
станет ложным. Он заканчивается, когда он проверяет flag
и находит его ложным. Это происходит только один раз каждый раз вокруг l oop. Вместо этого вы могли бы написать l oop как этот, и он будет вести себя точно так же:
while (true) {
if (! flag) break;
...
}
Так что, если у вас есть это,
while (flag) {
...executeFizz.await()...
}
И если flag
изменяется с истинного на ложное, когда поток застревает в вызове await()
, тогда l oop не прекратит работу до тех пор, пока после вызова await()
не вернется ...
... этого никогда не произойдет в вашем примере, потому что после того, как for
l oop сосчитал до n
, он устанавливает flag=false;
, но не сигнализирует другим ожидающие потоки.
@ SolomonSlow Я пытался сигнализировать все 3, но безуспешно после добавления условия if, в конце кода я включил этот код ...
Полагаю, это потому, что в вашей программе нет вызова lock.unlock()
. Вот что, вероятно, происходит:
Три «рабочих» потока все находятся в вызовах executeXxxxx.await()
(каждый ожидает свою собственную переменную условия.)
«Основной» поток достигает конца l oop (в настоящее время он является владельцем lock
,) и сигнализирует о каждой из executeXxxxxx
переменных состояния.
«Основной» поток заканчивается, но lock
все еще заблокирован. Все три «рабочих» потока теперь освобождены от ожидания соответствующих условий, но их вызовы await()
не могут вернуться, пока блокировка не станет доступной.
Блокировка никогда не станет доступно, потому что нет работающего потока, который может разблокировать его.
Вам нужно, чтобы каждый поток вызывал lock.unlock()
до его завершения.