Нет проблем с внедрением произвольных механизмов ожидания/уведомления с использованием LockSupport.park()
и LockSupport.unpark(Thread)
, поскольку эти базовые примитивы не требуют фиксации каких-либо замков.
Причина, почему ни Object.wait
/Object.notify
ни Condition
.await
/Condition.signal
предложение вам такое уведомление без проведения блокировки является семантическим один. Концепция уведомления заключается в том, что один поток ожидает выполнения условия, а другой останавливает ожидание, когда условие изменилось на выполненное состояние. Без фиксации, связанной с этим условием, нет гарантии, что условие не изменяется между тестами состояния состояния и изменением состояния потока.
Чтобы быть более конкретным, существует вероятность того, что когда поток, который изменил условие, уведомляет о другом потоке, это условие было изменено еще раз до того, как произойдет уведомление. Но еще хуже, условие может измениться на «выполнено» до того, как поток начнет wait
, и в этом случае поток может пропустить уведомление и вешать навсегда.
Даже если вы можете слить тестовое условие и операцию ожидания в одну атомную операцию, это не поможет. Ожидание состояния не является самоцелью. Причина, по которой поток хочет ждать условия, состоит в том, что он хочет выполнить действие , условие которого является необходимым условием и, следовательно, не должно меняться во время выполнения действия. В этом весь смысл: тест условия и действие должны быть реализованы как одна операция с блокировкой, независимо от того, как реализована концепция блокировки.
Существуют особые случаи, когда такие проблемы не могут возникнуть, например. когда известно, что переходы состояний состояния ограничены, поэтому вы можете исключить, что условие может вернуться к невыполненному состоянию. Вот именно такие инструменты, как CountDownLatch
, CyclicBarrier
, Phaser
, но механизм уведомления с предопределенной семантикой wait/notify подразумевает не предполагать такой особый случай.
«Lock» написан без использования wait/notify. Он использует CAS под капотом. –
Но нам еще нужно приобрести Lock для работы с его Условием. –
Не могли бы вы немного рассказать о том, что будут делать 'compareAndWait' и' setAndNotify'? 'compareAndWait' звучит как« Семафор »для меня, а' setAndNotify' звучит как 'BlockingQueue.put()'. – OldCurmudgeon