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 = new Runnable() { public void run() { mergeRows(...); }}; barrier = new CyclicBarrier(N, barrierAction); List<Thread> threads = new ArrayList<Thread>(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()
其他线程。
CountDownLatch
Constructor and Description |
---|
CyclicBarrier(int parties)
创建一个新的
CyclicBarrier ,当给定数量的线程(线程)等待它时,它将跳闸,并且当屏障跳闸时不执行预定义的动作。
|
CyclicBarrier(int parties, Runnable barrierAction)
创建一个新的
CyclicBarrier ,当给定数量的线程(线程)等待时,它将跳闸,当屏障跳闸时执行给定的屏障动作,由最后一个进入屏障的线程执行。
|
Modifier and Type | Method and Description |
---|---|
int |
await()
等待所有
parties已经在这个障碍上调用了
await 。
|
int |
await(long timeout, TimeUnit unit)
等待所有
parties已经在此屏障上调用
await ,或指定的等待时间过去。
|
int |
getNumberWaiting()
返回目前正在等待障碍的各方的数量。
|
int |
getParties()
返回旅行这个障碍所需的聚会数量。
|
boolean |
isBroken()
查询这个障碍是否处于破碎状态。
|
void |
reset()
将屏障重置为初始状态。
|
public CyclicBarrier(int parties, Runnable barrierAction)
CyclicBarrier
,当给定数量的线程(线程)正在等待时,它将跳闸,当屏障跳闸时执行给定的屏障动作,由最后一个进入屏障的线程执行。
parties
- 屏障跳闸前必须调用
await()
的线程数
barrierAction
- 当屏障跳闸时执行的命令,或
null
如果没有动作
IllegalArgumentException
- 如果
parties
小于1
public CyclicBarrier(int parties)
CyclicBarrier
,当给定数量的线程(线程)正在等待时,它将跳闸,并且当屏障跳闸时不执行预定义的动作。
parties
- 屏障跳闸前必须调用
await()
的线程数
IllegalArgumentException
- 如果
parties
小于1
public int getParties()
public int await() throws InterruptedException, BrokenBarrierException
await
。
如果当前线程不是最后一个线程,那么它被禁用以进行线程调度,并且处于休眠状态,直到发生下列事情之一:
reset()
。 如果当前线程:
InterruptedException
被关上,当前线程的中断状态被清除。
如果屏蔽是reset()
,而任何线程正在等待,或者当await
被调用时屏障is broken ,或者任何线程等待,则抛出BrokenBarrierException
。
如果任何线程在等待的时候是interrupted ,那么所有其他等待的线程将会丢失BrokenBarrierException
,并且屏障被置于断开的状态。
如果当前线程是要到达的最后一个线程,并且在构造函数中提供非空障碍操作,则当前线程在允许其他线程继续之前运行该动作。 如果在屏障动作期间发生异常,则该异常将在当前线程中传播,并且屏障置于断开状态。
getParties() - 1
表示第一个到达,零表示最后到达
InterruptedException
- 如果当前线程在等待时中断
BrokenBarrierException
- 如果当前线程正在等待,或者屏蔽被重置,或者当
await
时屏障被破坏,或者屏蔽动作(如果存在)由于异常而失败,则
另一个线程被中断或超时
public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException
await
,或指定的等待时间过去。
如果当前线程不是最后一个线程,那么它被禁用以进行线程调度,并且处于休眠状态,直到发生下列事情之一:
reset()
。 如果当前线程:
InterruptedException
被关上,当前线程的中断状态被清除。
如果指定的等待时间过去,则抛出TimeoutException
。 如果时间小于或等于零,该方法根本不会等待。
如果障碍是reset()
,而任何线程处于等待状态,或者如果屏障is broken时await
被调用,或在任何线程处于等待状态,然后BrokenBarrierException
被抛出。
如果任何线程在等待的时候是interrupted ,那么所有其他等待的线程将会抛出BrokenBarrierException
,并且屏障被置于断开的状态。
如果当前线程是要到达的最后一个线程,并且在构造函数中提供非空障碍操作,则当前线程在允许其他线程继续之前运行该动作。 如果在屏障动作期间发生异常,则该异常将在当前线程中传播,并且屏障置于断开状态。
timeout
- 等待屏障的时间
unit
- 超时参数的时间单位
getParties() - 1
表示第一个到达,零表示最后一个到达
InterruptedException
- 如果当前线程在等待时中断
TimeoutException
- 如果超过指定的超时。
在这种情况下,障碍将被破坏。
BrokenBarrierException
- 如果当前线程正在等待或
另一个线程被重置,或者
await
被调用时屏障被打破,或者屏蔽动作(如果存在)由于异常而失败,则线程被中断或超时
public boolean isBroken()
true
如果一个或多个参与方因施工或最后一次重置而导致中断或超时,或由于异常而导致屏障动作失败,则从此出现障碍;
false
否则。
public void reset()
BrokenBarrierException
。
注意,由于其他原因,发生断线后的复位可能会复杂化;
线程需要以其他方式重新同步,并选择一个执行重置。
可能更好地为后续使用创建新的屏障。
public int getNumberWaiting()
await()