CountDownLatch 介绍与举例实现

概述

CountDownLatchJUC 包下的一个重要的并发工具,它是一个线程协同作业的工具,使某些线程一直处于等待状态,直到另外的线程完成任务后再执行。

主要方法

CountDownLatch 主要靠内部的一个计数器来实现同步功能,其过程具有不可重复性

  • countDown() 方法:计数器的值 -1
  • getCount() 方法:获取当前计数器的值
  • await() 方法:当计数器的值不为 0 时,将阻塞所有调用此方法的线程,一直到计数器的值为 0 时,才会唤醒所有被此 CountDownLatch 对象阻塞的线程
  • await(long timeout, TimeUnit unit) 方法:在 await() 方法的基础上,增加了超时时间,以及增加了 boolean 类型的返回值。
    • timeout 的值小于或等于 0 时,将不会等待,若此时计数器的值为 0 ,则返回 true,否则返回 false
    • 当计数器在超时时间内,值归 0 了,则会正常返回 true,并执行唤醒操作。
    • 当超过了这个超时时间,计数器的值还未归 0,则会返回 false,也会执行唤醒操作。

举例实现

现有代码如下:

    static class MyRunnable implements Runnable {
        private int id;
        private CountDownLatch countDownLatch;
        public MyRunnable(int id, CountDownLatch countDownLatch) {
            this.id = id;
            this.countDownLatch = countDownLatch;
        }
        @Override
        public void run() {
            System.out.println("线程 :"+id+"正在执行......");
            try {
                Thread.sleep((int)(2000+(Math.random()*1000)));
            }catch (Exception ignored) {
            }
            countDownLatch.countDown();
            System.out.println("线程 :"+id+"执行结束!!!!!!");
        }
    }

    static class Runnable1 implements Runnable {
        private CountDownLatch countDownLatch;
        public Runnable1(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }
        @Override
        public void run() {
            System.out.println("线程 Runnable 1 开始执行, 需要等到 CountDownLatch 的计数为0时才会执行下一步操作");
            try {
                countDownLatch.await();
                System.out.println("线程 Runnable 1 终于执行完毕, 此时 CountDownLatch 中的计数为: "+countDownLatch.getCount());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(5);
        new Thread(new Runnable1(countDownLatch)).start();
        for (int i = 0;i<5;i++) {
            new Thread(new MyRunnable(i, countDownLatch)).start();
        }
        countDownLatch.await();
        System.out.println("全部线程执行结束, 现在主线程可以开始执行下一步操作, 此时 CountDownLatch 中的计数为: "+countDownLatch.getCount());
    }

代码运行结果为:

线程 Runnable 1 开始执行, 需要等到 CountDownLatch 的计数为0时才会执行下一步操作
线程 :0正在执行......
线程 :2正在执行......
线程 :3正在执行......
线程 :4正在执行......
线程 :1正在执行......
线程 :3执行结束!!!!!!
线程 :2执行结束!!!!!!
线程 :1执行结束!!!!!!
线程 :0执行结束!!!!!!
线程 :4执行结束!!!!!!
线程 Runnable 1 终于执行完毕, 此时 CountDownLatch 中的计数为: 0
全部线程执行结束, 现在主线程可以开始执行下一步操作, 此时 CountDownLatch 中的计数为: 0

可以看到,Runnable1 中的 run() 方法中的第一行打印语句最先执行,随后调用 countDownLatch.await() 方法后即被阻塞 ,其后一直等到所有的 MyRunnable 线程都执行结束后(即 CountDownLatch 的内部计数器值为 0 时),第二行打印语句才被执行。主线程中的打印语句亦如此。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值