Cyclic Barrier

使用

示意图
 @Test
  public void test() {
    int threadNum = 5;
    CyclicBarrier barrier =
        new CyclicBarrier(
            threadNum, () -> System.out.println(Thread.currentThread().getName() + " 完成最后任务"));
    for (int i = 0; i < threadNum; i++) {
      int finalI = i;
      new Thread(
              () -> {
                try {
                  System.out.println(finalI + " 到达栅栏 A");
                  barrier.await();
                  System.out.println(finalI + " 冲破栅栏 A");
                  System.out.println(finalI + " 到达栅栏 B");
                  barrier.await();
                  System.out.println(finalI + " 冲破栅栏 B");
                } catch (Exception e) {
                  e.printStackTrace();
                }
              })
          .start();
    }
  }

原理

img

有两个构造方法,只有带Runnable参数的构造方法才会在所有线程都到达等待点之后执行Runnable里面的run方法。

维护锁状态逻辑

其底层使用ReentrantLock+Condition进行锁状态的维护

具体看看其是如何实现等待逻辑的,线程等待需要调用await方法

最终调用的是dowait方法

可以看到,是通过index字段控制线程等待的,当index不为0的时候,线程统一会进行阻塞,直到index为0的时候,才会唤醒所有线程,这时候所有线程才会继续往下执行。

重复使用

这个跟CountdownLatch不一样的是,CountdownLatch是一次性的,而CycliBarrier是可以重复使用的,只需调用一下reset方法。

Last updated