CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。把一个大任务分成N个小任务让不同线程去执行,负责每个小任务的线程完成任务后阻塞挂起,完成任务数加1(内部操作,无需手动);当完成任务总数达到N时,执行 barrierAction 任务。
应用场景
CyclicBarrier 可以用于多线程计算数据,最后合并计算结果的应用场景。
测试代码
1 | public class CyclicBarrierTest { |
测试结果
原理分析
下面是 CyclicBarrier 的源码,可以看到它利用 ReentrantLock(可重入锁) 和 Condition 实现了线程等待与线程间通信,其实使用 CyclicBarrier 除了构造方法,关键就在 await() 方法中,虽然 CyclicBarrier 是加法计数,却不需要我们手动操作。

CyclicBarrier和CountDownLatch的区别
| CountDownLatch | CyclicBarrier |
|---|---|
| 减计数方式 | 加计数方式 |
| 计算为0时释放所有等待的线程 | 计数达到指定值时释放所有等待线程 |
| 计数为0时,无法重置 | 计数达到指定值时,计数置为0重新开始 |
| 调用countDown()方法计数减一,调用await()方法只进行阻塞,对计数没任何影响 | 调用await()方法计数加1,若加1后的值不等于构造方法的值,则线程阻塞 |
| 计算为0时释放所有等待的线程 | 计数达到指定值时释放所有等待线程 |
| 不可重复利用 | 可重复利用(reset) |