Spec-Zone .ru
спецификации, руководства, описания, API
|
public interface Condition
Condition
факторизует Object
методы монитора (wait
, notify
и notifyAll
) в отличные объекты дать эффект наличия наборов ожидания нескольких событий на объект, комбинируя их с использованием произвольных Lock
реализации. Где a Lock
заменяет использование synchronized
методы и операторы, a Condition
заменяет использование Объектных методов монитора. Условия (также известный как очереди условия или условные переменные) обеспечивают средство для одного потока, чтобы приостановить выполнение (чтобы "ожидать") пока не уведомлено другим потоком, что некоторое условие состояния может теперь быть истиной. Поскольку доступ к этой информации об общем состоянии происходит в различных потоках, это должно быть защищено, таким образом, блокировка некоторой формы связывается с условием. Ключевое свойство, которое обеспечивает ожидание условия, - то, что оно атомарно выпускает связанную блокировку и приостанавливает текущий поток, точно так же как Object.wait
.
A Condition
экземпляр свойственно связывается с блокировкой. Получить a Condition
экземпляр для детали Lock
использование экземпляра newCondition()
метод.
Как пример, предположите, что у нас есть ограниченный буфер, который поддерживает put
и take
методы. Если a take
предпринимается на пустом буфере, тогда поток блокирует, пока элемент не становится доступным; если a put
предпринимается на полном буфере, тогда поток блокирует, пока пространство не становится доступным. Мы хотели бы заставить ждать put
потоки и take
потоки в отдельных ожидать-наборах так, чтобы мы могли использовать оптимизацию только уведомления единственного потока в то время, когда элементы или пробелы становятся доступными в буфере. Это может быть достигнуто, используя два Condition
экземпляры.
class BoundedBuffer { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) notEmpty.await(); Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; notFull.signal(); return x; } finally { lock.unlock(); } } }(
ArrayBlockingQueue
class обеспечивает эту функциональность, таким образом нет никакой причины реализовать это демонстрационное использование class.) A Condition
реализация может обеспечить поведение и семантику, которая отличается от того из Object
методы монитора, такой как гарантирующийся упорядочивание для уведомлений, или не требование, чтобы блокировка была сохранена, выполняя уведомления. Если реализация обеспечивает такую специализированную семантику тогда, реализация должна задокументировать тех семантика.
Отметьте это Condition
экземпляры являются только нормальными объектами и могут самостоятельно использоваться в качестве цели в a synchronized
у оператора, и может быть их собственный монитор wait
и notification
методы вызываются. Получение блокировки монитора a Condition
у экземпляра, или использования его методов монитора, нет никакого указанного отношения с получением Lock
связанный с этим Condition
или использование его ожидания и сигнальных методов. Рекомендуется, чтобы, чтобы избежать беспорядка Вы никогда не использовали Condition
экземпляры таким образом, кроме, возможно, в пределах их собственной реализации.
Кроме где отмечено, передавая a null
значение для любого параметра приведет к a NullPointerException
быть брошенным.
Ожидая на a Condition
, "побочному пробуждению" разрешают произойти, вообще, как концессия базовой семантике платформы. Это оказывает небольшое практическое влияние на большинство прикладных программ как a Condition
на нужно всегда ожидать в цикле, тестируя предикат состояния, для которого ожидают. Реализация свободна удалить возможность побочных пробуждений, но рекомендуется, чтобы программисты приложений всегда предположили, что они могут произойти и так всегда ожидать в цикле.
Три формы ожидания условия (прерывистая, непрерывистая, и синхронизированный) могут отличаться по их непринужденности реализации на некоторых платформах и в их показателях производительности. В частности может быть трудно обеспечить эти функции и поддержать определенную семантику, такую как упорядочивание гарантий. Далее, возможность прервать фактическую приостановку потока, возможно, всегда не выполнима реализовать на всех платформах.
Следовательно, реализация не обязана определять точно те же самые гарантии или семантику для всех трех форм ожидания, и при этом это не требуется поддерживать прерывание фактической приостановки потока.
Реализация обязана ясно документировать семантику и гарантии, обеспеченные каждым из методов ожидания, и когда реализация действительно поддерживает прерывание приостановки потока тогда, это должно повиноваться семантике прерывания как определено в этом интерфейсе.
Поскольку прерывание обычно подразумевает отмену, и проверяет на прерывание, являются часто нечастыми, реализация может одобрить отвечание на прерывание по нормальному возврату метода. Это - истина, даже если можно показать, что прерывание произошло после другого действия, которое, возможно, разблокировало поток. Реализация должна задокументировать это поведение.
Модификатор и Тип | Метод и Описание |
---|---|
void |
await()
Заставляет текущий поток ожидать, пока он не сообщается или прерывается.
|
boolean |
await(long time, TimeUnit unit)
Заставляет текущий поток ожидать, пока он не сообщается или прерывается, или указанное время ожидания протекает.
|
long |
awaitNanos(long nanosTimeout)
Заставляет текущий поток ожидать, пока он не сообщается или прерывается, или указанное время ожидания протекает.
|
void |
awaitUninterruptibly()
Заставляет текущий поток ожидать, пока он не сообщается.
|
boolean |
awaitUntil(Date deadline)
Заставляет текущий поток ожидать, пока он не сообщается или прерывается, или указанный крайний срок протекает.
|
void |
signal()
Просыпается один поток ожидания.
|
void |
signalAll()
Просыпается все потоки ожидания.
|
void await() throws InterruptedException
Блокировка связалась с этим Condition
атомарно выпускается и текущий поток становится отключенным в целях планирования потоков и бездействует, пока одна из четырех вещей не происходит:
signal()
метод для этого Condition
и текущий поток, оказывается, выбирается в качестве потока, который будет пробужден; или signalAll()
метод для этого Condition
; или Во всех случаях, прежде, чем может возвратиться этот метод, текущий поток должен повторно получить блокировку, связанную с этим условием. Когда возвраты потока это, как гарантируют, будет содержать эту блокировку.
Если текущий поток:
InterruptedException
бросается и прерванное состояние текущего потока очищается. Это не определяется, в первом случае, происходит ли тест для прерывания прежде, чем блокировка выпускается. Соображения реализации
Текущий поток, как предполагается, содержит блокировку, связанную с этим Condition
когда этот метод вызывают. Это до реализации, чтобы определить, если это верно, и в противном случае как ответить. Как правило, исключение будет выдано (такой как IllegalMonitorStateException
) и реализация должна задокументировать тот факт.
Реализация может одобрить отвечание на прерывание по нормальному возврату метода в ответ на сигнал. В этом случае реализация должна гарантировать, что сигнал перенаправляется к другому потоку ожидания, если есть тот.
InterruptedException
- если текущий поток прерывается (и прерывание приостановки потока поддерживается),void awaitUninterruptibly()
Блокировка, связанная с этим условием, атомарно выпускается, и текущий поток становится отключенным в целях планирования потоков и бездействует, пока одна из трех вещей не происходит:
signal()
метод для этого Condition
и текущий поток, оказывается, выбирается в качестве потока, который будет пробужден; или signalAll()
метод для этого Condition
; или Во всех случаях, прежде, чем может возвратиться этот метод, текущий поток должен повторно получить блокировку, связанную с этим условием. Когда возвраты потока это, как гарантируют, будет содержать эту блокировку.
Если прерванное состояние текущего потока будет установлено, когда оно вводит этот метод, или оно прерывается, ожидая, то оно будет продолжать ожидать пока не сообщено. Когда это наконец возвратится из этого метода, его прерванное состояние будет все еще установлено.
Соображения реализации
Текущий поток, как предполагается, содержит блокировку, связанную с этим Condition
когда этот метод вызывают. Это до реализации, чтобы определить, если это верно, и в противном случае как ответить. Как правило, исключение будет выдано (такой как IllegalMonitorStateException
) и реализация должна задокументировать тот факт.
long awaitNanos(long nanosTimeout) throws InterruptedException
Блокировка, связанная с этим условием, атомарно выпускается, и текущий поток становится отключенным в целях планирования потоков и бездействует, пока одна из пяти вещей не происходит:
signal()
метод для этого Condition
и текущий поток, оказывается, выбирается в качестве потока, который будет пробужден; или signalAll()
метод для этого Condition
; или Во всех случаях, прежде, чем может возвратиться этот метод, текущий поток должен повторно получить блокировку, связанную с этим условием. Когда возвраты потока это, как гарантируют, будет содержать эту блокировку.
Если текущий поток:
InterruptedException
бросается и прерванное состояние текущего потока очищается. Это не определяется, в первом случае, происходит ли тест для прерывания прежде, чем блокировка выпускается. Метод возвращает оценку числа наносекунд, оставаясь ожидать данный предоставленный nanosTimeout
значение по возврату, или значение, меньше чем или равное нулю, если это синхронизированный. Это значение может использоваться, чтобы определить, ли и сколько времени повторно ожидать в случаях, где ожидать возвраты, но ожидаемое условие все еще не содержат. Типичное использование этого метода принимает следующую форму:
boolean aMethod(long timeout, TimeUnit unit) {
long nanos = unit.toNanos(timeout);
lock.lock();
try {
while (!conditionBeingWaitedFor()) {
if (nanos <= 0L)
return false;
nanos = theCondition.awaitNanos(nanos);
}
// ...
} finally {
lock.unlock();
}
}
Примечание проекта: Этот метод требует параметра наносекунды, чтобы избежать ошибок усечения в создании отчетов об остающихся временах. Такая потеря точности мешала бы программистам гарантировать, что полные времена ожидания не систематически короче чем указанный, когда повторно ожидает, происходят.
Соображения реализации
Текущий поток, как предполагается, содержит блокировку, связанную с этим Condition
когда этот метод вызывают. Это до реализации, чтобы определить, если это верно, и в противном случае как ответить. Как правило, исключение будет выдано (такой как IllegalMonitorStateException
) и реализация должна задокументировать тот факт.
Реализация может одобрить отвечание на прерывание по нормальному возврату метода в ответ на сигнал, или по указанию на протекание указанного времени ожидания. В любом случае реализация должна гарантировать, что сигнал перенаправляется к другому потоку ожидания, если есть тот.
nanosTimeout
- максимальное время, чтобы ожидать, в наносекундахnanosTimeout
значение минус время, проведенное, ожидая по возврату из этого метода. Положительное значение может использоваться в качестве параметра последующему звонку в этот метод, чтобы закончить пережидать требуемое время. Значение, меньше чем или равное нулю, не указывает то время, остается.InterruptedException
- если текущий поток прерывается (и прерывание приостановки потока поддерживается),boolean await(long time, TimeUnit unit) throws InterruptedException
awaitNanos(unit.toNanos(time)) > 0
time
- максимальное время, чтобы ожидатьunit
- единица измерения времени time
параметрfalse
если время ожидания, обнаруживаемо законченное перед возвратом из метода, еще true
InterruptedException
- если текущий поток прерывается (и прерывание приостановки потока поддерживается),boolean awaitUntil(Date deadline) throws InterruptedException
Блокировка, связанная с этим условием, атомарно выпускается, и текущий поток становится отключенным в целях планирования потоков и бездействует, пока одна из пяти вещей не происходит:
signal()
метод для этого Condition
и текущий поток, оказывается, выбирается в качестве потока, который будет пробужден; или signalAll()
метод для этого Condition
; или Во всех случаях, прежде, чем может возвратиться этот метод, текущий поток должен повторно получить блокировку, связанную с этим условием. Когда возвраты потока это, как гарантируют, будет содержать эту блокировку.
Если текущий поток:
InterruptedException
бросается и прерванное состояние текущего потока очищается. Это не определяется, в первом случае, происходит ли тест для прерывания прежде, чем блокировка выпускается. Возвращаемое значение указывает, протек ли крайний срок, который может использоваться следующим образом:
boolean aMethod(Date deadline) {
boolean stillWaiting = true;
lock.lock();
try {
while (!conditionBeingWaitedFor()) {
if (!stillWaiting)
return false;
stillWaiting = theCondition.awaitUntil(deadline);
}
// ...
} finally {
lock.unlock();
}
}
Соображения реализации
Текущий поток, как предполагается, содержит блокировку, связанную с этим Condition
когда этот метод вызывают. Это до реализации, чтобы определить, если это верно, и в противном случае как ответить. Как правило, исключение будет выдано (такой как IllegalMonitorStateException
) и реализация должна задокументировать тот факт.
Реализация может одобрить отвечание на прерывание по нормальному возврату метода в ответ на сигнал, или по указанию на передачу указанного крайнего срока. В любом случае реализация должна гарантировать, что сигнал перенаправляется к другому потоку ожидания, если есть тот.
deadline
- абсолютное время, чтобы ожидать доfalse
если крайний срок протек по возврату, еще true
InterruptedException
- если текущий поток прерывается (и прерывание приостановки потока поддерживается),void signal()
Если какие-либо потоки ожидают на этом условии тогда, каждый выбирается для того, чтобы проснуться. Тот поток должен тогда повторно получить блокировку прежде, чем возвратиться из await
.
Соображения реализации
Реализация может (и обычно делает), требуют, чтобы текущий поток содержал блокировку, связанную с этим Condition
когда этот метод вызывают. Реализации должны задокументировать это предварительное условие и любые меры, предпринятые, если блокировка не сохранена. Как правило, исключение такой как IllegalMonitorStateException
будет брошен.
void signalAll()
Если какие-либо потоки ожидают на этом условии тогда, они все будятся. Каждый поток должен повторно получить блокировку прежде, чем это сможет возвратиться из await
.
Соображения реализации
Реализация может (и обычно делает), требуют, чтобы текущий поток содержал блокировку, связанную с этим Condition
когда этот метод вызывают. Реализации должны задокументировать это предварительное условие и любые меры, предпринятые, если блокировка не сохранена. Как правило, исключение такой как IllegalMonitorStateException
будет брошен.
Для дальнейшей ссылки API и документации разработчика, см. Java Документация SE. Та документация содержит более подробные, предназначенные разработчиком описания, с концептуальными краткими обзорами, определениями сроков, обходных решений, и рабочих примеров кода.
Авторское право © 1993, 2013, Oracle и/или его филиалы. Все права защищены.
Проект сборка-b92