Класс CyclicBarrier
public class CyclicBarrier extends Object
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)
try {
thread.join();
} catch (InterruptedException ex) { }
}
} Здесь каждый рабочий поток обрабатывает строку матрицы, а затем ожидает барьер, пока все строки не будут обработаны. Когда все строки обработаны, заданное Runnable действие барьера выполняется и строки объединяются. Если объединение определяет, что решение найдено, то done() вернёт true и каждый рабочий поток завершит свою работу. Если действие барьера не зависит от приостановки сторон при его выполнении, любой из потоков в группе может выполнить это действие при освобождении. Для этого каждый вызов await() возвращает индекс прибытия этого потока в барьер. Затем вы можете выбрать, какой поток должен выполнить действие барьера, например:
if (barrier.await() == 0) {
// log the completion of this iteration
} The CyclicBarrier использует модель нарушения «всё или ничего» для неудачных попыток синхронизации: если поток преждевременно покидает точку барьера из-за прерывания, ошибки или таймаута, все остальные потоки, ожидающие в этой точке барьера, также покинут аномально через BrokenBarrierException (или InterruptedException, если они также были прерваны примерно в одно и то же время).
Эффекты согласованности памяти: действия в потоке перед вызовом await() происходят-перед действиями, которые являются частью действия барьера, которые, в свою очередь, происходят-перед действиями, следующими за успешным возвращением от соответствующего await() в других потоках.
- Since:
- 1.5
- См. также:
Краткое описание конструкторов
| Конструктор | Описание |
|---|---|
CyclicBarrier |
Создаёт новый CyclicBarrier , который сработает, когда заданное количество сторон (потоков) будет ждать его, и не выполняет предварительно определённого действия, когда барьер срабатывает. |
CyclicBarrier |
Создаёт новый CyclicBarrier , который сработает, когда заданное количество сторон (потоков) будет ждать его, и который выполнит заданное действие барьера, когда барьер сработает, выполняемое последним потоком, вошедшим в барьер. |
Краткое описание методов
| Модификатор и тип | Метод | Описание |
|---|---|---|
int |
await() |
Ожидает, пока все стороны не вызовут await в этом барьере. |
int |
await |
Ожидает, пока все стороны не вызовут await в этом барьере, или не истечёт указанное время ожидания. |
int |
getNumberWaiting() |
Возвращает количество сторон, которые в данный момент ожидают в барьере. |
int |
getParties() |
Возвращает количество сторон, необходимое для срабатывания этого барьера. |
boolean |
isBroken() |
Определяет, находится ли этот барьер в состоянии нарушения. |
void |
reset() |
Сбрасывает барьер в его начальное состояние. |
Подробное описание конструкторов
CyclicBarrier
public CyclicBarrier(int parties, Runnable barrierAction)
- Параметры:
-
parties- количество потоков, которые должны вызватьawait(), прежде чем барьер срабатывает -
barrierAction- команда для выполнения, когда барьер срабатывает, илиnullесли нет действия - Исключения:
-
IllegalArgumentException- еслиpartiesменьше 1
CyclicBarrier
public CyclicBarrier(int parties)
- Параметры:
-
parties- количество потоков, которые должны вызватьawait(), прежде чем барьер срабатывает - Исключения:
-
IllegalArgumentException- еслиpartiesменьше 1
Подробное описание методов
getParties
public int getParties()
- Возвращает:
- количество участников, необходимое для срабатывания этого барьера
await
public int await() throws InterruptedException, BrokenBarrierException
await в этом барьере. Если текущий поток не является последним, прибывшим, то он отключается для планирования потоков и находится в спящем состоянии до тех пор, пока не произойдёт одно из следующих событий:
- Прибывает последний поток; или
- Другой поток прерывает текущий поток; или
- Другой поток прерывает один из других ожидающих потоков; или
- Другой поток выходит за пределы ожидания барьера; или
- Другой поток вызывает
reset()в этом барьере.
Если текущий поток:
- имеет установленный статус прерывания при входе в этот метод; или
- прерывается во время ожидания
InterruptedException, и статус прерывания текущего потока сбрасывается. Если барьер reset() во время ожидания какого-либо потока, или если барьер сломан при вызове await, или в то время, когда какой-либо поток ожидает, то будет брошено исключение BrokenBarrierException.
Если какой-либо поток прерывается во время ожидания, то все остальные ожидающие потоки бросят исключение BrokenBarrierException, и барьер переходит в состояние разрыва.
Если текущий поток является последним, прибывшим, и в конструкторе был передан ненулевой action барьера, то текущий поток выполняет действие перед тем, как разрешить другим потокам продолжить. Если во время выполнения действия барьера произойдёт исключение, то это исключение будет распространено в текущем потоке, и барьер перейдёт в состояние разрыва.
- Возвращает:
- индекс прибытия текущего потока, где индекс
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, и барьер переходит в состояние разрыва.
Если текущий поток является последним, прибывшим, и в конструкторе был передан ненулевой action барьера, то текущий поток выполняет действие перед тем, как разрешить другим потокам продолжить. Если во время выполнения действия барьера произойдёт исключение, то это исключение будет распространено в текущем потоке, и барьер перейдёт в состояние разрыва.
- Параметры:
-
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, 2023, 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/21/docs/api/java.base/java/util/concurrent/CyclicBarrier.html