JUC学习系列七(同步屏障 CyclicBarrier)

一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。

CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。

public class Dragon {

    public void getBall(CyclicBarrier cb,int index){
        try {
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName()+"获得"+index+"星龙珠!");
            cb.await();
        } catch ( Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
       final CyclicBarrier cb=new CyclicBarrier(7, new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"集齐七颗龙珠召唤神龙!");
            }
        });
       final Dragon d=new Dragon();

        for (int i=1;i<8;i++){
           final int j=i;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    d.getBall(cb,j);
                }
            }).start();
        }
        //检测重用性
        for (int i=1;i<8;i++){
            final int j=i;
            new Thread(new Runnable() {
                @Override
                public void run() {
//                   int b= 8/(j-5);
                    d.getBall(cb,j);
                }
            }).start();
        }
    }

}

这个工具类使用起来比较简单。API中的异常破坏模式,内存一致性还没弄懂。后面在做补充吧!

源码剖析

结构:

我们在实例中new CyclicBarrier时,给它一个数目7和一个触发事件,在类中它们对应的就是parties和barrierCommand,如下:

这个类就只有一个await()常用。我们看看它的底层到底是是怎样一个流程吧!

 

 dowait()后面还有一个自旋方法,只要作用是当前线程阻塞时,检测它是否被打断等作用。感兴趣了可以自行阅读,比较简单。

 当前线程被打断时,或者中途抛出了异常在finally代码块里,调用的方法:

初始化以便复用的方法:

 以上就是其执行的原理。其中利用到了ReentrantLock。它自身也有一个count的int类型数值做计数器,跟AQS的思想很相近,当这个count减为0的时候,触发构造器里的线程任务类。每次调用await()方法,会使这个count计数器减一。中间也考虑到线程打断等情况,掺杂了相关的处理。源码还是很容易理解的。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值