Класс CyclicBarrier
- java.lang.Object
-
- java.util.concurrent.CyclicBarrier
public class CyclicBarrier extends Object
Средство синхронизации, которое позволяет набору потоков ожидать друг друга в общей точке барьера. CyclicBarriers полезны в программах, включающих фиксированный набор потоков, которые должны время от времени ждать друг друга. Барьер называется циклическим, потому что его можно повторно использовать после того, как ожидающие потоки будут освобождены.
A CyclicBarrier поддерживает необязательную Runnable команду, которая выполняется один раз на точку барьера после того, как последняя нить в группе прибудет, но перед тем, как любые потоки будут освобождены. Эта действие барьера полезна для обновления общего состояния, прежде чем любая из сторон продолжит.
Пример использования: Вот пример использования барьера в параллельном декомпозиционном дизайне:
class Solver {
final int N;
final float[][] data;
final CyclicBarrier barrier;
class Worker implements Runnable {
int myRow;
Worker(int row) { myRow = row; }
public void run() {
while (!done()) {
processRow(myRow);
try {
barrier.await();
} catch (InterruptedException ex) {
return;
} catch (BrokenBarrierException ex) {
return;
}
}
}
}
public Solver(float[][] matrix) {
data = matrix;
N = matrix.length;
Runnable barrierAction = () -> mergeRows(...);
barrier = new CyclicBarrier(N, barrierAction);
List<Thread> threads = new ArrayList<>(N);
for (int i = 0; i < N; i++) {
Thread thread = new Thread(new Worker(i));
threads.add(thread);
thread.start();
}
// wait until done
for (Thread thread : threads)
thread.join();
}
} Здесь каждый рабочий поток обрабатывает строку матрицы, а затем ждет у барьера, пока все строки не будут обработаны. Когда все строки обработаны, заданное Runnable действие барьера выполняется и объединяет строки. Если объединение определит, что решение найдено, то done() вернёт true и каждый рабочий поток завершится. Если действие барьера не зависит от приостановки сторон во время его выполнения, то любой из потоков в группе может выполнить это действие при его освобождении. Для облегчения этого каждое вызов await() возвращает индекс прибытия этого потока в барьер. Затем вы можете выбрать, какой поток должен выполнить действие барьера, например:
if (barrier.await() == 0) {
// log the completion of this iteration
} CyclicBarrier использует модель разрыва «все или ничего» для неудачных попыток синхронизации: если поток оставляет точку барьера преждевременно из-за прерывания, ошибки или истечения времени, все остальные потоки, ожидающие в этой точке барьера, также покинут аномально через BrokenBarrierException (или InterruptedException, если они также были прерваны примерно в то же время).
Эффекты согласованности памяти: Действия в потоке до вызова await() происходят-до действий, которые являются частью действия барьера, а это, в свою очередь, происходят-до действий, следующих за успешным возвратом из соответствующего await() в других потоках.
- С тех пор:
- 1.5
- См. также:
CountDownLatch
Конструкторы
| Конструктор | Описание |
|---|---|
CyclicBarrier(int parties) | Создаёт новый |
CyclicBarrier(int parties,
Runnable barrierAction) | Создаёт новый |
Методы
| Модификатор и тип | Метод | Описание |
|---|---|---|
int | await() | Ожидает, пока все стороны не вызовут |
int | await(long timeout,
TimeUnit unit) | Ожидает, пока все стороны не вызовут |
int | getNumberWaiting() | Возвращает количество сторон, которые в настоящее время ожидают у барьера. |
int | getParties() | Возвращает количество сторон, необходимых для срабатывания этого барьера. |
boolean | isBroken() | Запрашивает, находится ли этот барьер в состоянии разрыва. |
void | reset() | Сбрасывает барьер в его начальное состояние. |
Методы, объявленные в классе java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait Конструкторы
CyclicBarrier
public CyclicBarrier(int parties,
Runnable barrierAction) Создаёт новый CyclicBarrier, который будет срабатывать, когда заданное количество участников (потоков) будут ожидать его, и который выполнит заданное действие барьера, когда барьер сработает, выполненное последним потоком, вступившим в барьер.
- Параметры:
-
parties- количество потоков, которые должны вызватьawait(), прежде чем барьер сработает -
barrierAction- команда для выполнения, когда барьер срабатывает, илиnull, если нет действия - Исключения:
-
IllegalArgumentException- еслиpartiesменьше 1
CyclicBarrier
public CyclicBarrier(int parties)
Создаёт новый CyclicBarrier, который будет срабатывать, когда заданное количество участников (потоков) будут ожидать его, и не выполняет предварительно определённого действия, когда барьер срабатывает.
- Параметры:
-
parties- количество потоков, которые должны вызватьawait(), прежде чем барьер сработает - Исключения:
-
IllegalArgumentException- еслиpartiesменьше 1
Методы
getParties
public int getParties()
Возвращает количество участников, необходимых для срабатывания этого барьера.
- Возвращает:
- количество участников, необходимых для срабатывания этого барьера
await
public int await()
throws InterruptedException,
BrokenBarrierException Ожидает, пока все участники не вызовут await для этого барьера.
Если текущий поток не является последним, который прибыл, то он отключается для целей планирования потоков и находится в спящем режиме, пока не произойдёт одно из следующих событий:
- Прибывает последний поток; или
- Некоторые другие поток прерывает текущий поток; или
- Некоторые другие поток прерывает один из других ожидающих потоков; или
- Некоторые другие поток превышает время ожидания, ожидая барьера; или
- Некоторые другие поток вызывает
reset()для этого барьера.
Если текущий поток:
- установил свой флаг прерывания при входе в этот метод; или
- прерывается прерывается во время ожидания
InterruptedException, и флаг прерывания текущего потока сбрасывается. Если барьер reset() в то время, когда какой-либо поток ожидает, или если барьер разрушен, когда await вызывается, или в то время как какой-либо поток ожидает, выбрасывается BrokenBarrierException.
Если какой-либо поток прерывается во время ожидания, все другие ожидающие потоки выбросят BrokenBarrierException, и барьер переведётся в состояние разрыва.
Если текущий поток является последним, который прибыл, и в конструкторе был указан не нулевой параметр действия барьера, то текущий поток выполняет действие до того, как позволяет другим потокам продолжить. Если при выполнении действия барьера происходит исключение, то это исключение будет передано в текущий поток, и барьер будет переведён в состояние разрыва.
- Возвращает:
- индекс прибытия текущего потока, где индекс
getParties() - 1обозначает первый пришедший, а ноль обозначает последний - Исключения:
-
InterruptedException- если текущий поток был прерван во время ожидания -
BrokenBarrierException- если другой поток был прерван или истекло время ожидания, пока текущий поток ожидал, или барьер был сброшен, или барьер был разрушен, когдаawaitбыл вызван, или действие барьера (если присутствует) завершилось с ошибкой
await
public int await(long timeout,
TimeUnit unit)
throws InterruptedException,
BrokenBarrierException,
TimeoutException Ожидает, пока все участники не вызовут await для этого барьера, или не истечёт заданное время ожидания.
Если текущий поток не является последним, который прибыл, то он отключается для целей планирования потоков и находится в спящем режиме, пока не произойдёт одно из следующих событий:
- Прибывает последний поток; или
- Истекает заданное время ожидания; или
- Некоторые другие поток прерывает текущий поток; или
- Некоторые другие поток прерывает один из других ожидающих потоков; или
- Некоторые другие поток превышает время ожидания, ожидая барьера; или
- Некоторые другие поток вызывает
reset()для этого барьера.
Если текущий поток:
- установил свой флаг прерывания при входе в этот метод; или
- прерывается прерывается во время ожидания
InterruptedException, и флаг прерывания текущего потока сбрасывается. Если заданное время ожидания истекает, то выбрасывается TimeoutException. Если время меньше или равно нулю, метод вообще не будет ожидать.
Если барьер reset() в то время, когда какой-либо поток ожидает, или если барьер разрушен, когда await вызывается, или в то время как какой-либо поток ожидает, выбрасывается BrokenBarrierException.
Если какой-либо поток прерывается во время ожидания, все другие ожидающие потоки выбросят BrokenBarrierException, и барьер переведётся в состояние разрыва.
Если текущий поток является последним, который прибыл, и в конструкторе был указан не нулевой параметр действия барьера, то текущий поток выполняет действие до того, как позволяет другим потокам продолжить. Если при выполнении действия барьера происходит исключение, то это исключение будет передано в текущий поток, и барьер будет переведён в состояние разрыва.
- Параметры:
-
timeout- время ожидания барьера -
unit- единица измерения времени параметра таймаута - Возвращает:
- индекс прибытия текущего потока, где индекс
getParties() - 1обозначает первый пришедший, а ноль обозначает последний - Исключения:
-
InterruptedException- если текущий поток был прерван во время ожидания -
TimeoutException- если заданное время ожидания истекает. В этом случае барьер будет разрушен. -
BrokenBarrierException- если другой поток был прерван или истекло время ожидания, пока текущий поток ожидал, или барьер был сброшен, или барьер был разрушен, когдаawaitбыл вызван, или действие барьера (если присутствует) завершилось с ошибкой
isBroken
public boolean isBroken()
Определяет, находится ли этот барьер в состоянии разрыва.
- Возвращает:
-
trueесли один или несколько участников вышли из этого барьера из-за прерывания или истечения времени ожидания с момента создания или последнего сброса, или действие барьера завершилось с ошибкой;falseв противном случае.
reset
public void reset()
Сбрасывает барьер в исходное состояние. Если какие-либо участники в настоящее время ожидают у барьера, они вернутся с BrokenBarrierException. Обратите внимание, что сбросы после того, как произошёл сбой по другим причинам, могут быть сложными для выполнения; потоки должны повторно синхронизироваться каким-то другим способом и выбрать один для выполнения сброса. Возможно, предпочтительнее вместо этого создать новый барьер для последующего использования.
getNumberWaiting
public int getNumberWaiting()
Возвращает количество участников, которые в настоящее время ожидают у барьера. Этот метод в основном полезен для отладки и утверждений.
- Возвращает:
- количество участников, которые в настоящее время заблокированы в
await()
© 1993, 2020, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/CyclicBarrier.html