概述
-
CyclicBarrier 是一个同步辅助类,它允许一组线程相互等待直到所有线程都到达一个公共的屏障点.
-
在程序中有固定数量的线程,这些线程有时候必须等待彼此.
-
这个屏障之所以用循环修饰,是因为在所有的线程释放彼此之后,这个屏障是可以重新使用的.
我们启动 N 个线程去做一件事情,只有当这 N 个线程都达到某一个临界点的时候,我们才能继续下面的工作,就是说如果这 N 个线程中的某一个线程先到达预先定义好的临界点,它必须等待其他 N-1 线程也到达这个临界点,接下来的工作才能继续,只要这 N 个线程中有1个线程没有到达所谓的临界点,其他线程就算抢先到达了临界点,也只能等待,只有所有这 N 个线程都到达临界点后,接下来的事情才能继续.
API
// parties 必须到达的线程数
CyclicBarrier(int parties)
// barrierAction 最后一个线程到达时,在解除屏障前,执行的方法
CyclicBarrier(int parties, Runnable barrierAction)
// 在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待.
int await()
// 在所有参与者都已经在此屏障上调用 await 方法之前将一直等待,或者超出了指定的等待时间.
int await(long timeout, TimeUnit unit)
// 返回当前在屏障处等待的参与者数目.
int getNumberWaiting()
// 返回要求启动此 barrier 的参与者数目.
int getParties()
// 查询此屏障是否处于损坏状态.
boolean isBroken()
// 将屏障重置为其初始状态.
void reset()
使用
/**
* 假若有若干个线程都要进行写数据操作,并且只有所有线程都完成写数据操作之后,这些线程才能继续做后面的事情
* 如果说想在所有线程写入操作完之后,进行额外的其他操作可以为 CyclicBarrier 提供 Runnable 参数
*/
public class CyclicBarrierTest {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(2, new Runnable() {
@Override
public void run() {
System.out.println("当前线程" + Thread.currentThread().getName());
}
});
for (int i = 0; i < 2; i++){
new Writer(barrier).start();
}
}
static class Writer extends Thread {
private CyclicBarrier cyclicBarrier;
public Writer(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
try {
Thread.sleep(1000);
cyclicBarrier.await();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("线程执行完毕,继续其他任务...");
}
}
}