Существует фундаментальное свойство await
(которое относится к внутренней блокировке через synchronized
и также с использованием Object.wait
), вы должны понимать:
Когда вы вызываете await
,вы снимаете блокировку , с которой связана Condition
.Обойти его невозможно, иначе никто не сможет получить блокировку, выполнить условие и вызвать для него signal
.
Когда ваш ожидающий поток получает сигнал, он не получает блокировку.вернуться немедленно.Это было бы невозможно, поскольку поток, вызвавший signal
, все еще владеет им.Вместо этого получатель будет пытаться повторно получить блокировку, мало чем отличаясь от вызова lockInterruptibly()
.
Но этот поток не обязательно является единственным потоком, пытающимся получить блокировку.Это даже не должно быть первым.Другой поток мог прибыть на put
до сигнализации и ожидания блокировки на lockInterruptibly()
.Таким образом, даже если блокировка была корректной (что обычно не происходит), сигнальный поток не имеет приоритета.Даже если вы указали приоритет сигнальных потоков, может быть несколько потоков, о которых было сообщено по разным причинам.
Таким образом, другой поток, достигший put
, может получить блокировку перед сигнальным потоком, найти место и сохранитьэлемент, даже не заботясь о сигналах.Затем, к тому времени, когда сигнализируемый поток получил блокировку, условие больше не выполняется.Таким образом, сигнализируемый поток никогда не может полагаться на действительность условия только потому, что он получил сигнал, и поэтому должен повторно проверить условие и снова вызвать await
, если он не выполнен.
Это делает проверку условия вцикл стандартная идиома использования await
, как описано в Condition
интерфейс , а также Object.wait
для случая использования встроенного монитора, только для полноты,Другими словами, это даже не относится к конкретному API.
Так как условие должно быть предварительно проверено и проверено в любом случае в цикле, спецификация даже допускает ложных пробуждений событие возврата потока из операции ожидания без фактического получения сигнала.Это может упростить реализацию блокировок на определенных платформах, не изменяя способ использования блокировки.
important Важно подчеркнуть, что при удержании нескольких блокировок только блокировка, связанная сусловие освобождено.