Most visited

Recently visited

Added in API level 1

CyclicBarrier

public class CyclicBarrier
extends Object

java.lang.Object
   ↳ java.util.concurrent.CyclicBarrier


一种同步辅助,它允许一组线程互相等待以达到共同的障碍点。 CyclicBarriers在涉及固定大小的线程的程序中很有用,它必须偶尔等待对方。 该屏障称为循环,因为它可以在等待线程释放之后重新使用。

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 =
       new Runnable() { public void run() { 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();
   }
 }
Here, each worker thread processes a row of the matrix then waits at the barrier until all rows have been processed. When all rows are processed the supplied Runnable barrier action is executed and merges the rows. If the merger determines that a solution has been found then done() will return true and each worker will terminate.

如果屏障行为不依赖于执行时被暂停的方,那么当方被释放时,方中的任何线程都可以执行该行为。 为了实现这一点,每次调用await()返回该线程到达屏障的索引。 然后,您可以选择执行屏障操作的线程,例如:

 if (barrier.await() == 0) {
   // log the completion of this iteration
 }

CyclicBarrier对失败的同步尝试使用全或非破坏模型:如果线程由于中断,失败或超时而过早离开障碍点,则在该障碍点等待的所有其他线程也将通过 BrokenBarrierException (或 InterruptedException如果他们也几乎同时被打断)。

内存一致性影响:在调用 await() happen-before之前的线程中的动作,这些动作是屏障动作的一部分,而这些动作又 发生 -在其他线程中相应的 await()成功返回后的动作 之前

也可以看看:

Summary

Public constructors

CyclicBarrier(int parties, Runnable barrierAction)

创建一个新的 CyclicBarrier ,当给定数量的参与方(线程)等待时,它会跳闸,并且在屏障被跳闸时执行给定的屏障动作,由最后一个线程进入屏障执行。

CyclicBarrier(int parties)

创建一个新的 CyclicBarrier ,当给定数量的参与方(线程)等待它时会跳闸,并且在障碍触发时不执行预定义的操作。

Public methods

int await()

等待所有 parties已在此屏障上调用 await

int await(long timeout, TimeUnit unit)

等待所有 parties已在此屏障上调用 await ,或者经过指定的等待时间。

int getNumberWaiting()

返回当前在障碍处等待的参与者的数量。

int getParties()

返回跳过此障碍所需的参与方数量。

boolean isBroken()

查询此屏障是否处于故障状态。

void reset()

将屏障重置为初始状态。

Inherited methods

From class java.lang.Object

Public constructors

CyclicBarrier

Added in API level 1
CyclicBarrier (int parties, 
                Runnable barrierAction)

创建一个新的 CyclicBarrier ,当给定数量的参与方(线程)等待时,它会跳闸,并且在屏障被跳闸时执行给定的屏障动作,由最后一个线程进入屏障执行。

Parameters
parties int: the number of threads that must invoke await() before the barrier is tripped
barrierAction Runnable: the command to execute when the barrier is tripped, or null if there is no action
Throws
IllegalArgumentException if parties is less than 1

CyclicBarrier

Added in API level 1
CyclicBarrier (int parties)

创建一个新的 CyclicBarrier ,当给定数量的参与方(线程)等待它时会跳闸,并且在障碍被触发时不执行预定义的操作。

Parameters
parties int: the number of threads that must invoke await() before the barrier is tripped
Throws
IllegalArgumentException if parties is less than 1

Public methods

await

Added in API level 1
int await ()

等待所有 parties在此屏障上调用 await

如果当前线程不是最后到达的线程,则为线程调度目的而禁用它,并且处于休眠状态,直到发生以下某种情况:

  • The last thread arrives; or
  • Some other thread interrupts the current thread; or
  • Some other thread interrupts one of the other waiting threads; or
  • Some other thread times out while waiting for barrier; or
  • Some other thread invokes reset() on this barrier.

如果当前线程:

  • has its interrupted status set on entry to this method; or
  • is interrupted while waiting
then InterruptedException is thrown and the current thread's interrupted status is cleared.

如果障碍是 reset() ,而任何线程处于等待状态,或者如果屏障 is brokenawait被调用,或在任何线程处于等待状态,然后 BrokenBarrierException被抛出。

如果任何线程在等待期间为 interrupted ,则所有其他等待的线程将抛出 BrokenBarrierException ,屏障处于断开状态。

如果当前线程是最后一个到达的线程,并且在构造函数中提供了非空屏障操作,则当前线程在允许其他线程继续之前运行该操作。 如果在屏障动作期间发生异常,那么该异常将在当前线程中传播并且屏障被置于断开状态。

Returns
int the arrival index of the current thread, where index getParties() - 1 indicates the first to arrive and zero indicates the last to arrive
Throws
InterruptedException if the current thread was interrupted while waiting
BrokenBarrierException if another thread was interrupted or timed out while the current thread was waiting, or the barrier was reset, or the barrier was broken when await was called, or the barrier action (if present) failed due to an exception

await

Added in API level 1
int await (long timeout, 
                TimeUnit unit)

等待所有 parties已在此屏障上调用 await ,或者经过指定的等待时间。

如果当前线程不是最后到达的线程,则为线程调度目的而禁用它,并且处于休眠状态,直到发生以下某种情况:

  • The last thread arrives; or
  • The specified timeout elapses; or
  • Some other thread interrupts the current thread; or
  • Some other thread interrupts one of the other waiting threads; or
  • Some other thread times out while waiting for barrier; or
  • Some other thread invokes reset() on this barrier.

如果当前线程:

  • has its interrupted status set on entry to this method; or
  • is interrupted while waiting
then InterruptedException is thrown and the current thread's interrupted status is cleared.

如果经过了指定的等待时间,则引发TimeoutException 如果时间小于或等于零,该方法将不会等待。

如果障碍是 reset() ,而任何线程处于等待状态,或者如果屏障 is brokenawait被调用,或在任何线程处于等待状态,然后 BrokenBarrierException被抛出。

如果任何线程在等待期间为 interrupted ,则其他所有等待的线程将抛出 BrokenBarrierException ,屏障处于断开状态。

如果当前线程是最后一个到达的线程,并且在构造函数中提供了非空屏障操作,则当前线程在允许其他线程继续之前运行该操作。 如果在屏障动作期间发生异常,那么该异常将在当前线程中传播并且屏障被置于断开状态。

Parameters
timeout long: the time to wait for the barrier
unit TimeUnit: the time unit of the timeout parameter
Returns
int the arrival index of the current thread, where index getParties() - 1 indicates the first to arrive and zero indicates the last to arrive
Throws
InterruptedException if the current thread was interrupted while waiting
TimeoutException if the specified timeout elapses. In this case the barrier will be broken.
BrokenBarrierException if another thread was interrupted or timed out while the current thread was waiting, or the barrier was reset, or the barrier was broken when await was called, or the barrier action (if present) failed due to an exception

getNumberWaiting

Added in API level 1
int getNumberWaiting ()

返回当前在障碍处等待的参与者的数量。 此方法主要用于调试和断言。

Returns
int the number of parties currently blocked in await()

getParties

Added in API level 1
int getParties ()

返回跳过此障碍所需的参与方数量。

Returns
int the number of parties required to trip this barrier

isBroken

Added in API level 1
boolean isBroken ()

查询此屏障是否处于故障状态。

Returns
boolean true if one or more parties broke out of this barrier due to interruption or timeout since construction or the last reset, or a barrier action failed due to an exception; false otherwise.

reset

Added in API level 1
void reset ()

将屏障重置为初始状态。 如果任何一方当前正在屏障等待,他们将返回BrokenBarrierException 请注意,由于其他原因发生破损重置可能会很复杂; 线程需要以其他方式重新同步,并选择一个来执行重置。 相反,为后续使用创造一个新的屏障可能更好。

Hooray!