JUC--CyclicBarrier简介和使用

1 概述

CyclicBarrier允许一组线程相互等待,直到到达某个公共的屏障点这组线程才继续执行。在涉及一组固定大小的线程的程序当中,这组线程必须相互等待,这个时候CyclicBarrier就显得非常有用了,由于Barrier(栅栏)在释放线程后可以从新使用,所以Barrier被称为Cyclic(循环)Barrier(栅栏)。

2 示例

下面我们来看看CyclicBarrier是如何使用的。

public class CyclicBarrierTest {
    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(5, () -> System.out.println("all thread complete"));

    public static void main(String[] args) {
        for (int i = 0; i <5 ; i++) {
            new Thread(() -> {
                try {
                    System.out.println(Thread.currentThread().getId()+" running!");
                    cyclicBarrier.await();
                    System.out.println(Thread.currentThread().getId()+" running again!");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
        System.out.println("main begin");
    }
}

程序执行的结果:

main begin
14 running!
15 running!
13 running!
17 running!
16 running!
all thread complete
16 running again!
17 running again!
13 running again!
15 running again!
14 running again!

从上面的运行结果我们可以看出来5个线程等待直到所有线程等待完成的时候再继续开始执行。

3 函数说明

  • await():在所有参与者都已经在此barrier 上调用await 方法之前,将一直等待。
  • await(long timeout, TimeUnit unit):在所有参与者都已经在此屏障上调用await 方法之前将一直等待,或者超出了指定的等待时间。
  • getNumberWaiting():返回当前在屏障处等待的参与者数目。此方法主要用于调试和断言。 
  • getParties():返回要求启动此barrier 的参与者数目。 
  • isBroken():查询此屏障是否处于损坏状态。 
  • reset():将屏障重置为其初始状态。

4 与CountDownLatch的区别

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

上面就是对CyclicBarrier使用的介绍,接下来将进行源码的分析。

    原文作者:JUC
    原文地址: https://blog.csdn.net/ONROAD0612/article/details/82387945
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞