- java.lang.Object
-
- java.util.concurrent.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) thread.join(); } }
Runnable
屏障操作并合并行。 如果合并确定已经找到解决方案,那么done()
将返回true
并且每个工作人员将终止。如果屏障操作不依赖于执行方暂停的各方,那么该方可以在释放任何线程时执行该操作。 为了方便这一点,每次调用
await()
会将该线程的到达索引返回到屏障。 然后,您可以选择哪个线程应该执行屏障操作,例如:if (barrier.await() == 0) { // log the completion of this iteration }
CyclicBarrier
对失败的同步尝试使用all-or-none断裂模型:如果线程由于中断,故障或超时而过早离开障碍点,则在该障碍点等待的所有其他线程也将异常通过BrokenBarrierException
(或InterruptedException
如果他们也在同一时间被打断)。内存一致性效应:在调用
await()
happen-before之前的线程中的操作,这些操作是屏障动作的一部分,而这些操作反过来发生在其他线程中相应的await()
成功返回后的操作之前 。- 从以下版本开始:
- 1.5
- 另请参见:
-
CountDownLatch
-
-
构造方法摘要
构造方法 Constructor 描述 CyclicBarrier(int parties)
创建一个新的CyclicBarrier
,当给定数量的线程(线程)等待它时,它将跳闸,并且当屏障跳闸时不执行预定义的动作。CyclicBarrier(int parties, Runnable barrierAction)
创建一个新的CyclicBarrier
,当给定数量的线程(线程)等待它时,它将跳闸,当屏障跳闸时执行给定的屏障动作,由最后一个线程进入屏障执行。
-
方法摘要
所有方法 接口方法 具体的方法 Modifier and Type 方法 描述 int
await()
等待直到所有的 parties已经在这个障碍上调用了await
。int
await(long timeout, TimeUnit unit)
等待直到所有 parties已经在此屏障上调用了await
,或指定的等待时间过去。int
getNumberWaiting()
返回目前正在等待障碍的各方的数量。int
getParties()
返回旅行这个障碍所需的聚会数量。boolean
isBroken()
询问这个障碍是否处于破碎状态。void
reset()
将屏障重置为初始状态。
-
-
-
构造方法详细信息
-
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
等待,直到所有的parties已经在这个障碍上调用了await
。如果当前线程不是最后一个线程,那么它被禁用以进行线程调度,并且处于休眠状态,直到发生下列事情之一:
- 最后一个线程到达; 要么
- 一些其他线程interrupts当前线程; 要么
- 一些其他线程interrupts其他等待线程之一; 要么
- 一些其他线程在等待屏障时超时; 要么
- 其他一些线程会在此屏障上调用
reset()
。
如果当前线程:
- 在进入该方法时设置了中断状态; 要么
- 是等待interrupted
InterruptedException
并清除当前线程的中断状态。如果障碍是
reset()
,而任何线程处于等待状态,或者如果屏障is broken时await
被调用,或在任何线程处于等待状态,然后BrokenBarrierException
被抛出。如果任何线程在等待的时候是interrupted ,那么所有其他等待的线程将会抛出
BrokenBarrierException
,并且屏障被置于断开的状态。如果当前线程是要到达的最后一个线程,并且在构造函数中提供非空障碍操作,则当前线程在允许其他线程继续之前运行该动作。 如果在屏障动作期间发生异常,则该异常将在当前线程中传播,并且屏障置于断开状态。
- 结果
-
当前线程的到达索引,其中索引
getParties() - 1
表示第一个到达,零表示最后到达 - 异常
-
InterruptedException
- 如果当前线程在等待时中断 -
BrokenBarrierException
-如果 另一个线程被中断或超时在当前线程在等待,或阻挡被复位或者当屏障被破坏await
叫,或阻挡动作(如果存在)失败,由于一个异常
-
await
public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException
等待直到所有parties已经在此屏障上调用了await
,或指定的等待时间过去。如果当前线程不是最后一个线程,那么它被禁用以进行线程调度,并且处于休眠状态,直到发生下列事情之一:
- 最后一个线程到达; 要么
- 超过指定的超时 要么
- 一些其他线程interrupts当前线程; 要么
- 一些其他线程interrupts其他等待线程之一; 要么
- 一些其他线程在等待屏障时超时; 要么
- 其他一些线程会在此屏障上调用
reset()
。
如果当前线程:
- 在进入该方法时设置了中断状态; 要么
- 是等待interrupted
InterruptedException
,并清除当前线程的中断状态。如果指定的等待时间过去,则抛出
TimeoutException
。 如果时间小于或等于零,该方法根本不会等待。如果障碍是
reset()
,而任何线程处于等待状态,或者如果屏障is broken时await
被调用,或在任何线程处于等待状态,然后BrokenBarrierException
被抛出。如果任何线程在等待时为interrupted ,则所有其他等待线程将抛出
BrokenBarrierException
,并且屏障置于断开状态。如果当前线程是要到达的最后一个线程,并且在构造函数中提供非空障碍操作,则当前线程在允许其他线程继续之前运行该动作。 如果在屏障动作期间发生异常,则该异常将在当前线程中传播,并且屏障置于断开状态。
- 参数
-
timeout
- 等待屏障的时间 -
unit
- 超时参数的时间单位 - 结果
-
当前线程的到达索引,其中索引
getParties() - 1
表示第一个到达,零表示最后到达 - 异常
-
InterruptedException
- 如果当前线程在等待时中断 -
TimeoutException
- 如果TimeoutException
指定的超时。 在这种情况下,障碍将被破坏。 -
BrokenBarrierException
- 如果 另一个线程在当前线程正在等待或屏蔽被重置时被中断或超时,或者当await
时屏障被破坏,或者屏蔽动作(如果存在)由于异常而失败
-
isBroken
public boolean isBroken()
询问这个障碍是否处于破碎状态。- 结果
-
true
如果一个或多个政党由于施工或最后一次重置而导致中断或超时,或由于例外而导致屏障行动失败,则出现此障碍; 否则为false
。
-
reset
public void reset()
将屏障重置为初始状态。 如果任何一方正在等待障碍,他们将返回BrokenBarrierException
。 注意,由于其他原因,发生断线后的复位可能会复杂化; 线程需要以其他方式重新同步,并选择一个执行重置。 可能更好地为后续使用创建新的屏障。
-
getNumberWaiting
public int getNumberWaiting()
返回目前正在等待障碍的各方的数量。 此方法主要用于调试和断言。- 结果
-
目前阻止的当事人数在
await()
-
-