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()
成功返回后的动作 之前 。
也可以看看:
Public constructors |
|
---|---|
CyclicBarrier(int parties, Runnable barrierAction) 创建一个新的 |
|
CyclicBarrier(int parties) 创建一个新的 |
Public methods |
|
---|---|
int |
await() 等待所有 parties已在此屏障上调用 |
int |
await(long timeout, TimeUnit unit) 等待所有 parties已在此屏障上调用 |
int |
getNumberWaiting() 返回当前在障碍处等待的参与者的数量。 |
int |
getParties() 返回跳过此障碍所需的参与方数量。 |
boolean |
isBroken() 查询此屏障是否处于故障状态。 |
void |
reset() 将屏障重置为初始状态。 |
Inherited methods |
|
---|---|
From class java.lang.Object
|
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 (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 |
int await ()
等待所有 parties在此屏障上调用 await
。
如果当前线程不是最后到达的线程,则为线程调度目的而禁用它,并且处于休眠状态,直到发生以下某种情况:
reset()
on this barrier. 如果当前线程:
InterruptedException
is thrown and the current thread's interrupted status is cleared.
如果障碍是 reset()
,而任何线程处于等待状态,或者如果屏障 is broken时 await
被调用,或在任何线程处于等待状态,然后 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 |
int await (long timeout, TimeUnit unit)
等待所有 parties已在此屏障上调用 await
,或者经过指定的等待时间。
如果当前线程不是最后到达的线程,则为线程调度目的而禁用它,并且处于休眠状态,直到发生以下某种情况:
reset()
on this barrier. 如果当前线程:
InterruptedException
is thrown and the current thread's interrupted status is cleared.
如果经过了指定的等待时间,则引发TimeoutException
。 如果时间小于或等于零,该方法将不会等待。
如果障碍是 reset()
,而任何线程处于等待状态,或者如果屏障 is broken时 await
被调用,或在任何线程处于等待状态,然后 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 |
int getNumberWaiting ()
返回当前在障碍处等待的参与者的数量。 此方法主要用于调试和断言。
Returns | |
---|---|
int |
the number of parties currently blocked in await() |
int getParties ()
返回跳过此障碍所需的参与方数量。
Returns | |
---|---|
int |
the number of parties required to trip this barrier |
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. |
void reset ()
将屏障重置为初始状态。 如果任何一方当前正在屏障等待,他们将返回BrokenBarrierException
。 请注意,由于其他原因发生破损后重置可能会很复杂; 线程需要以其他方式重新同步,并选择一个来执行重置。 相反,为后续使用创造一个新的屏障可能更好。