CountDownLatch和CyclicBarrier

CountDownLatch和CyclicBarrier
两个类都是java并发包java.util.concurrent中提供的控制线程的使用类。使用如下:
CountDownLatch的一个使用场景就是充当裁判的角色,等待


public static void main(String[] args) {
        CountDownLatch cdl = new CountDownLatch(1);
        CountDownLatch bizCdl = new CountDownLatch(5);
        for (int i = 0; i < 5; i++) {
            executorService.execute(new MySporter(cdl,bizCdl,"运动员"+i));
        }
        try {
            //模拟准备时间
            Thread.sleep(3000);
            //发令
            System.out.println("预备开始,啪");
            cdl.countDown();
            bizCdl.await();
            System.out.println("等待所有运动员跑到终点后,开始统计成绩");
           
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{
           //释放资源
          executorService.shutdown();
        }
    }
   /**
    *模拟运动员
    */
    public class MySporter implements Runnable {
    //主裁判
    private CountDownLatch countDownLatch;
    //运动员监控
    private CountDownLatch bizCountDownlatch;
    private String  name;
    public MySporter() {
    }
    public MySporter(CountDownLatch countDownLatch,CountDownLatch bizCountDownlatch,String  name) {
        this.countDownLatch = countDownLatch;
        this.bizCountDownlatch=bizCountDownlatch;
        this.name = name;
    }
    @Override
    public void run() {
        System.out.println("myname is "+name + " wait");
        try {
            //等待裁判吹开始哨
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(name+"跑到终点了");
        //跑到终点后,运动员监控跟着递减
        bizCountDownlatch.countDown();
    }
    ...
}

执行结果如下:

myname is 运动员0 wait
myname is 运动员1 wait
myname is 运动员2 wait
myname is 运动员3 wait
myname is 运动员4 wait
预备开始,啪
运动员1跑到终点了
运动员2跑到终点了
运动员3跑到终点了
运动员0跑到终点了
运动员4跑到终点了
等待所有运动员跑到终点后,开始统计成绩

CyclicBarrier是充当屏障的作用,等待所有的worker工作完成后,在同一个时刻集合,然后再进行后续的操作;代码如下:

 public static void main(String[] args) {
        int n = 4;
        CyclicBarrier cb = new CyclicBarrier(n, new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "当前线程做后续的事情");
            }
        });
        for (int l = 0; l < n; l++) {
            new Thread(new Writer(cb)).start();
        }

    }

    static class Writer implements Runnable {
        private CyclicBarrier cb;

        public Writer() {
        }

        public Writer(CyclicBarrier cb) {
            this.cb = cb;
        }

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + "当前进程开始进行IO操作");
            try {
                //模拟io操作
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName() + "执行完IO操作");
                //等待其他线程 
                cb.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "开始进行自己的业务操作");
        }
    }

执行结果如下:

Thread-0当前进程开始进行IO操作
Thread-1当前进程开始进行IO操作
Thread-2当前进程开始进行IO操作
Thread-3当前进程开始进行IO操作
Thread-2执行完IO操作
Thread-3执行完IO操作
Thread-1执行完IO操作
Thread-0执行完IO操作
Thread-0当前线程做后续的事情
Thread-0开始进行自己的业务操作
Thread-2开始进行自己的业务操作
Thread-1开始进行自己的业务操作
Thread-3开始进行自己的业务操作

从结果可以看出,当四个线程都到达品屏障后,会从四个线程中选择最后一个线程去执行CyclicBarrier中的Runnable操作。另外,barrier也是可以复用的。

总结:

区别CountDownLatchCyclicBarrier
等待1充当发令枪,触发子线程操作2等待所有子线程完成任务后,再执行主线程业务一组线程互相等待
复用不支持支持
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值