简介
CyclicBarrier也是java并发包中的一个工具类,也被称为同步屏障,作用是可以让一组线程达到一个屏障时阻塞,直到最后一个线程到达屏障时,所有被阻塞的线程才能继续执行。
示意图如下:
下面将从源码的角度来看看CyclicBarrier并发类,如无特殊说明,本文JDK版本为1.8
构造方法
该类中有2个构造方法,分别来看下:
- 参数表示屏障拦截的线程数量,每个线程调用await方法告诉CyclicBarrier已经到达屏障位置,线程被阻塞
- 比第一个构造方法多了一个参数barrierAction,表示在所有线程到达屏障后执行
实现原理
CyclicBarrier实现主要基于ReentrantLock,本文就不介绍了ReentrantLock,不清楚以的[请点击](https://starlin.top/2018/07/09/java%E5%B9%B6%E5%8F%91/java
%E5%B9%B6%E5%8F%91%E4%B9%8BReentrantLock/)了解详情,
await()实现
内部其实是调用dowait()来实现
源代码如下:
大概过程如下:
- 每当线程执行await,内部变量count减1,如果count不等于0,说明有线程未到达屏障处,则在锁条件变量trip上等待
- 当count等于0,说明所有线程都到达屏障处,开始执行signalAll方法,唤醒其他等待线程,其中nextGeneration()可以实现屏障的循环使用
- 重新生成Generation对象
- 恢复count值
应用场景
假设某一个部门团建,要求每一位员工上午11点集合,统一出发
在这个例子中将部门作为一个主线程,每位员工作为一个子线程,Demo如下:
运行可能结果如下:
与CountDownLatch的区别
-
CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行;
-
CyclicBarrier可以循环使用,而CountDownLatch不是循环使用的
end,感谢阅读!!!