多线程编程之CyclicBarrier 源码分析

CyclicBarrier 源码分析之怎么卷死 CountDownLatch

CyclicBarrier 是什么?

CyclicBarrier 一般称为栅栏、屏障,是一种多线程同步工具。

常常和 CountDownLatch一起作比较,因为都属于用于一组线程等待的工具。

不同于 CountDownLatch常用于协调线程等待一组工作线程,且工作线程到达后做一次通知并继续执行,CyclicBarrier 人如其名的是一组线程相互等待全部到达指定处后,再全部继续执行。

CyclicBarrier更高级的是:

  • 允许重用,执行完成后或手动重置即可重新使用;CountDownLatch直接报废。

  • 允许执行回调逻辑,一般是最后一个到达栅栏的线程自调用。我们可以用这个特性在业务逻辑中执行收尾工作。

  • 出现问题可破坏当前分代(通知其他线程),重置进行下一次。不同于 CountDownLatch达到指定条件处后就不关心结果,CyclicBarrier必须等待在栅栏。如果某个工作线程在到达前出现异常,那就需要人为处理重置。

    当然出现异常、超时等情况也会自动破坏当前使用,但是注意并不能直接进行下一次使用,必须手动重置。

CyclicBarrier 怎么用?

CountDownLatch:几道锁的保险箱 (juejin.cn) cue 到 CyclicBarrier说打开保险锁后,就不能再用了。

image-20210621163638007

允许重用

亲信当然希望开锁拿钱跑路以后,老板回来检查就不会发现。image-20210621164945886

private static void normal() throws InterruptedException {
   
    CyclicBarrier barrier = new CyclicBarrier(3);
    if (!barrier.isBroken()) {
   
        System.out.println("保险箱:安全保护中");
    }
    System.out.println("亲信们:不成功便成仁!!!!!");
    for (int i = 0; i < 3; i++) {
   
        Thread thread = new Thread(new MyFollower(barrier));
        thread.start();
    }
    Thread.sleep(1000);
    if (!barrier.isBroken()) {
   
        System.out.println("保险箱:安全保护中");
        System.out.println("老板:很好,这东西不错");
    }
}

private static class MyFollower implements Runnable {
   
    private CyclicBarrier barrier;

    public MyFollower(CyclicBarrier barrier) {
   
        this.barrier = barrier;
    }

    @Override
    public void run() {
   
        System.out.println("亲信:输入密码ing");
        try {
   
            barrier.await();
        } catch (InterruptedException e) {
   
            System.out.println("临死前:骂骂咧咧地退出了游戏");
        } catch (BrokenBarrierException e) {
   
            System.out.println("OS:傻子,这都输入错了");
        }
        System.out.println("亲信:成了!!!!!");
    }
}
保险箱:安全保护中
    
亲信们:不成功便成仁!!!!!
    
亲信:输入密码ing
亲信:输入密码ing
亲信:输入密码ing
    
亲信:成了!!!!!
亲信:成了!!!!!
亲信:成了!!!!!
    
保险箱:安全保护中
老板:很好,这东西不错
亲信被杀(中断)、输入错了(主动破坏)、输入慢了(超时)的情况下,关我保险锁什么事?

由于内部线程中断、或主动破坏都是校验一个布尔值,因此这种情况下其他线程无法知道什么原因导致破坏。

image-20210621174527946

简单实现代码(真实情况肯定是需要更完善的协调和处理的)

private static void normal() throws InterruptedException {
   
    CyclicBarrier barrier = new CyclicBarrier(3);
    if (!barrier.isBroken()) {
   
        System.out.println("保险箱:安全保护中"
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值