CyclicBarrier 是什么?从字面上的意思可以知道,这个类的中文意思是“循环栅栏”。大概的意思就是一个可循环利用的屏障。 它的作用就是会让一组线程叨叨一个屏障点(或者称之为同步点)时被阻塞,知道最后一个线程到达屏障点时候,其他所有被阻塞的线程都会继续运行。

    举个例子,就像生活中我们会约朋友们到某个景点一起游玩,有些朋友可能会早到,有些朋友可能会晚到,但是这个景点肯定是一起进入检票。所以每个朋友到的时候都会阻塞,直到最后一个朋友达到的时候,其他朋友才继续执行。

    CyclicBarrier 的默认构造器是 public CyclicBarrier(int parties) 其参数标识屏障阻拦线程的个数,每个线程调用 await() 的时候都会告诉 CyclicBarrier 我已达到屏障,然后当前线程阻塞。

    20181218144511688.gif

    图片来源: https://blog.csdn.net/qq_39241239/article/details/87030142

    下面的代码清单是 CyclicBarrier 常用的编程的范式:

    1. public static void main(String[] args) throws Exception {
    2. CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
    3. // 线程1
    4. new Thread(
    5. () -> {
    6. try {
    7. // 进入屏障点,此时主线程还未调用最后一次 await(),因此会阻塞
    8. cyclicBarrier.await();
    9. } catch (Exception ignore) {}
    10. })
    11. .start();
    12. // 线程2
    13. new Thread(
    14. () -> {
    15. try {
    16. // 进入屏障点,此时主线程还未调用最后一次 await(),因此会阻塞
    17. cyclicBarrier.await();
    18. } catch (Exception ignore) {}
    19. })
    20. .start();
    21. TimeUnit.SECONDS.sleep(10);
    22. // CyclicBarrier 设置的参数为3 ,这是最后一次调用
    23. // 当此次调用完成后,线程1和线程2 的阻塞会被放开
    24. cyclicBarrier.await();
    25. }

    另外,CyclicBarrier 也有另外一个构造方法 public CyclicBarrier(int parties, Runnable barrierAction) 当线程到达屏障时候,会有限执行 barrierAction

    可以预知的是,CyclicBarrier 的内部实现逻辑肯是一种通知等待逻辑,事实上,通过看源码我们也知道内部持有一个 ReentrantLock 可重入锁 用户并发访问,每一次调用await都会是count— ,如果count == 0, 那么则会开启屏障,继续执行,否则执行 ReentrantLock.__Condition 等待通知。
    _