CyclicBarrier
时间:2020-01-09 10:36:26 来源:igfitidea点击:
java.util.concurrent.CyclicBarrier类是一种同步机制,可以同步通过某种算法进行的线程。换句话说,这是所有线程必须继续等待直到所有线程到达它的屏障。
线程通过在CyclicBarrier上调用await()方法来互相等待。一旦N个线程在" CyclicBarrier"上等待,所有线程将被释放并可以继续运行。
创建一个CyclicBarrier
当创建一个" CyclicBarrier"时,我们指定释放它之前要等待多少个线程。这是创建" CyclicBarrier"的方法:
CyclicBarrier barrier = new CyclicBarrier(2);
在CyclicBarrier中等待
这是线程在CyclicBarrier中等待的方式:
barrier.await();
我们还可以为等待的线程指定超时。当超时时间过去后,即使不是所有的N个线程都在" CyclicBarrier"上等待,该线程也会被释放。这是我们指定超时的方法:
barrier.await(10, TimeUnit.SECONDS);
等待线程在CyclicBarrier处等待,直到:
- 最后一个线程到达(调用await())
- 该线程被另一个线程中断(另一个线程调用其interrupt()方法)
- 另一个等待线程被中断
- 在
CyclicBarrier中等待时,另一个等待线程超时 - 某些外部线程会调用" CyclicBarrier.reset()"方法。
循环屏障动作
" CyclicBarrier"支持屏障操作,这是一个" Runnable",在最后一个线程到达时执行。我们将" Runnable"屏障操作传递给其构造函数中的" CyclicBarrier",如下所示:
Runnable barrierAction = ... ; CyclicBarrier barrier = new CyclicBarrier(2, barrierAction);
CyclicBarrier示例
这是一个代码示例,向我们展示如何使用CyclicBarrier:
Runnable barrier1Action = new Runnable() {
public void run() {
System.out.println("BarrierAction 1 executed ");
}
};
Runnable barrier2Action = new Runnable() {
public void run() {
System.out.println("BarrierAction 2 executed ");
}
};
CyclicBarrier barrier1 = new CyclicBarrier(2, barrier1Action);
CyclicBarrier barrier2 = new CyclicBarrier(2, barrier2Action);
CyclicBarrierRunnable barrierRunnable1 =
new CyclicBarrierRunnable(barrier1, barrier2);
CyclicBarrierRunnable barrierRunnable2 =
new CyclicBarrierRunnable(barrier1, barrier2);
new Thread(barrierRunnable1).start();
new Thread(barrierRunnable2).start();
这是CyclicBarrierRunnable类:
public class CyclicBarrierRunnable implements Runnable{
CyclicBarrier barrier1 = null;
CyclicBarrier barrier2 = null;
public CyclicBarrierRunnable(
CyclicBarrier barrier1,
CyclicBarrier barrier2) {
this.barrier1 = barrier1;
this.barrier2 = barrier2;
}
public void run() {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() +
" waiting at barrier 1");
this.barrier1.await();
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() +
" waiting at barrier 2");
this.barrier2.await();
System.out.println(Thread.currentThread().getName() +
" done!");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
这是执行上述代码的控制台输出。请注意,线程执行写入控制台的顺序可能因执行而异。有时会先显示"线程-0",有时会先打印" Thread-1",依此类推。
Thread-0 waiting at barrier 1 Thread-1 waiting at barrier 1 BarrierAction 1 executed Thread-1 waiting at barrier 2 Thread-0 waiting at barrier 2 BarrierAction 2 executed Thread-0 done! Thread-1 done!

