- java.lang.Object
-
- java.util.concurrent.CyclicBarrier
-
public class CyclicBarrier extends Object
一种同步辅助工具,允许一组线程全部等待彼此到达公共障碍点。 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 = () -> 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()
之前的线程中的操作happen-before作为屏障操作的一部分的操作,该操作又发生在从其他线程中的相应await()
成功返回之后的操作之前 。- 从以下版本开始:
- 1.5
- 另请参见:
-
CountDownLatch
-
-
构造方法摘要
构造方法 构造器 描述 CyclicBarrier(int parties)
创建一个新的CyclicBarrier
,当给定数量的参与方(线程)等待它时将跳闸,并且当屏障被触发时不执行预定义的操作。CyclicBarrier(int parties, Runnable barrierAction)
创建一个新的CyclicBarrier
,当给定数量的参与方(线程)等待它时将跳闸,并且当屏障被触发时执行给定的屏障操作,由进入屏障的最后一个线程执行。
-
-
-
构造方法详细信息
-
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
并且屏障处于断开状态。如果当前线程是要到达的最后一个线程,并且在构造函数中提供了非null屏障操作,则当前线程在允许其他线程继续之前运行该操作。 如果在屏障操作期间发生异常,则该异常将在当前线程中传播,并且屏障处于断开状态。
- 结果
-
当前线程的到达索引,其中索引
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
并且屏障处于断开状态。如果当前线程是要到达的最后一个线程,并且在构造函数中提供了非null屏障操作,则当前线程在允许其他线程继续之前运行该操作。 如果在屏障操作期间发生异常,则该异常将在当前线程中传播,并且屏障处于断开状态。
- 参数
-
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()
中被阻止的各方数量
-
-