Класс 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, который сработает, когда указанное количество сторон (потоков) будут ожидать его, и не выполняет предварительно определённого действия, когда барьер срабатывает.

CyclicBarrier​(int parties, Runnable barrierAction)

Создаёт новый CyclicBarrier, который сработает, когда указанное количество сторон (потоков) будут ожидать его, и который выполнит заданное действие барьера, когда барьер срабатывает, выполненное последним входящим в барьер потоком.

Методы

Модификатор и тип Метод Описание
int await()

Ожидает, пока все стороны не вызовут await в этом барьере.

int await​(long timeout, TimeUnit unit)

Ожидает, пока все стороны не вызовут await в этом барьере, или указанное время ожидания истечёт.

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

Spec-Zone .ru
спецификации, руководства, описания, API