CyclicBarrier介绍
CyclicBarrier运行一组线程相互等待,直到到达某个公共的屏障点。
它是通过计数器来实现的,当某个线程调用了await()方法后,该线程就进入了等待状态,计数器执行加1操作,当计数器的值达到了设置的初始值的时候,调用await()进入等待状态的线程会被唤醒,继续执行他们后续的操作。由于CyclicBarrier在释放等待线程后可以重用,所以我们又称它为循环屏障。
CyclicBarrier和CountDownLatch区别
- CountDownLatch的计数器只能使用一次,CyclicBarrier的计数器可以使用reset()方法重置,循环使用
- CountDownLatch主要实现一个或多个线程需要等待其他线程完成某项操作后,才能继续往下执行,CyclicBarrier实现了多个线程互相等待,直到所有线程都满足条件之后,才能继续执行后续操作
CycliBarrier的实例
public class TestCyclicBarrier {
private static CyclicBarrier cyclicBarrier=new CyclicBarrier(5);
public static void main(String[] args) throws InterruptedException {
ExecutorService pool = Executors.newCachedThreadPool();
for(int i=0;i<10;i++){
final int threadNum=i;
Thread.sleep(1000);
pool.execute(new Runnable() {
@Override
public void run() {
race(threadNum);
}
});
}
pool.shutdown();
}
private static void race(int threadNum) {
try {
Thread.sleep(1000);
System.out.println("ready"+threadNum);
cyclicBarrier.await();
System.out.println("continue"+threadNum);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
上面的例子可以看出任务 0-4 全都执行完ready之后,再一起执行continue。
任务 5-9 全都执行完ready之后,再一起执行continue。即将5个线程作为一组,当5个线程都到达指定屏障后,所有任务才会被唤醒继续执行。
在声明CyclicBarrier的时候,还可以指定Runnable表明当线程达到指定屏障后,优先执行Runnable。
private static CyclicBarrier cyclicBarrier=new CyclicBarrier(5,new Runnable() {
@Override
public void run() {
System.out.println("到达");
}
});