前言
CyclicBarrier的字面意思是:可循环使用(cyclic)的屏障(barrier)。通过它可以实现让一组线程等待至某个状态之后再全部同时执行。
使用
1 | /** |
源码分析
构造函数
1 | public CyclicBarrier(int parties) { |
从 CyclicBarrier 的源码中,我们可以看到该类有两个构造函数,最终是使用CyclicBarrier(int parties, Runnable barrierAction)
。其中的 Runnable 类型的参数是在:当给定数量的线程处于等待时,会触发屏障CyclicBarrier,当屏障被触发时执行该命令
。
await源码
1 | public int await() throws InterruptedException, BrokenBarrierException { |
在 CyclicBarrier 中,无论是带有超时的await还是没有带超时的await方法,最终调用的都是 dowait() 方法。
dowait源码
1 | private int dowait(boolean timed, long nanos) |
该方法是 CyclicBarrier 类的核心。逻辑为:
- 获取可重入锁。成功获取,执行下一步;获取失败,等待
- 判断屏障是否已经
broken
。是,抛出BrokenBarrierException
异常;否则,执行下一步。 - 判断当前线程是否被中断。已中断,则调用breakBarrier()方法将屏障
broken
,然后抛出InterruptedException
异常;否则,执行下一步。 - 更新已经到达屏障(barrier)的线程数
index = --count
。 - 如果
index==0
,则说明所以线程都已到达屏障,则执行barrierCommand
任务,并更新generation,然后返回,方法结束。 - 如果
index!=0
,则进入for循环。- 调用Condition类的相关方法将线程进去等待状态
- 判断generation的状态及是否等待已超时。
breakBarrier源码
1 | // 当某个线程被中断 / 等待超时 则将 broken = true, 并且唤醒所有等待中的线程 |
nextGeneration源码
1 | //生成下一个 generation |
isBroken源码
1 | //判断 barrier 是否 broken = true |
该方法用来判断阻塞的线程是否被中断
reset源码
1 | //将屏障重置为初始状态。 |
getNumberWaiting源码
1 | //Returns the number of parties currently waiting at the barrier. |
该方法用于获取在屏障处阻塞的线程。