CountDownLatch用法

官方定义:A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
有道翻译:一种同步辅助程序,允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。

个人理解,实际就是一个倒计时计数器,人为指定计数器的起始值,从起始值开始倒计时计数。
主要方法:

await():阻塞,直到倒计时为0开始执行;
countDown():倒计时方法,没执行一次减一,如果新计数为零,则所有等待的线程都将被重新启用;
getCount():返回当前计数。

说这么多,也不知道到底是个啥,看例子:
例1:
三个运动员百米赛跑,一个裁判倒计时发枪。裁判需要等待运动员全部都准备好了,才会发枪
所以这段时间裁判需要除以等待状态,当所有的运动员都汇报准备好了,裁判发枪

//也就是说await()会一直等待CountDownLatch的初始值全部countDown()后才会线下执行
public static void main(String[] args) {

        CountDownLatch latch = new CountDownLatch(3);

        Thread t1 = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("博尔特准备完毕");
                latch.countDown();
                System.out.println("剩下的记数器:"+latch.getCount());
            }
        },"t1");

        Thread t2 = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(7000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("加特林准备完毕");
                latch.countDown();
                System.out.println("剩下的记数器:"+latch.getCount());
            }
        },"t2");

        Thread t3 = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("鲍威尔准备完毕");
                latch.countDown();
                System.out.println("剩下的记数器:"+latch.getCount());
            }
        },"t3");

        t1.start();
        t2.start();
        t3.start();

        try {
            System.out.println("我是裁判,你们好好准备,准备好了都说一声....");
            latch.await();
            System.out.println("好的,都准备好了,我要发枪了");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

运行结果:

我是裁判,你们好好准备,准备好了都说一声...
博尔特准备完毕
剩下的记数器:2
加特林准备完毕
剩下的记数器:1
鲍威尔准备完毕
剩下的记数器:0
好的,都准备好了,我要发枪了

例2:
其实刚才说的是裁判等运动员准备的过程,实际上细细分析,我们会发现,实际上也有一个运动员等枪响的动作。运动员听见枪响后,同时起跑。

public static void main(String[] args) {
        CountDownLatch latch = new CountDownLatch(1);

        Thread t1 = new Thread(new Runnable() {
            public void run() {
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("博尔特起跑");
            }
        },"t1");

        Thread t2 = new Thread(new Runnable() {
            public void run() {
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("鲍威尔起跑");
            }
        },"t2");

        Thread t3 = new Thread(new Runnable() {
            public void run() {
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("加特林起跑");
            }
        },"t3");

        t1.start();
        t2.start();
        t3.start();

        try {
            System.out.println("各就位");
            Thread.sleep(3000);
            System.out.println("发枪....");
            latch.countDown();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

运行结果:

各就位
发枪....
博尔特起跑
加特林起跑
鲍威尔起跑

例3

模拟发枪起跑,到运动员跑完全程,比赛结束的过程:

public static void main(String[] args) {

        CountDownLatch start = new CountDownLatch(1);
        CountDownLatch end = new CountDownLatch(3);

        Thread t1 = new Thread(new Runnable() {
            public void run() {
                try {
                    start.await();
                    System.out.println("博尔特起跑");

                    Thread.sleep(9580);

                    System.out.println("博尔特跑完了全程");
                    end.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"t1");

        Thread t2 = new Thread(new Runnable() {
            public void run() {
                try {
                    start.await();
                    System.out.println("鲍威尔起跑");

                    Thread.sleep(9760);

                    System.out.println("鲍威尔跑完了全程");
                    end.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"t2");

        Thread t3 = new Thread(new Runnable() {
            public void run() {
                try {
                    start.await();
                    System.out.println("加特林起跑");

                    Thread.sleep(9620);

                    System.out.println("加特林跑完了全程");
                    end.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"t3");

        t1.start();
        t2.start();
        t3.start();

        try {
            System.out.println("各就位");
            Thread.sleep(1000);
            System.out.println("发枪.....");
            start.countDown();
            Thread.sleep(2000);
            System.out.println("这是一场精彩的比赛");
            Thread.sleep(2000);
            System.out.println("加特林加速");
            Thread.sleep(2000);
            System.out.println("博尔特反超");
            Thread.sleep(2000);
            System.out.println("博尔特一直保持领先");

            end.await();
            System.out.println("比赛结束");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

运行结果:

各就位
发枪.....
鲍威尔起跑
加特林起跑
博尔特起跑
这是一场精彩的比赛
加特林加速
博尔特反超
博尔特一直保持领先
博尔特跑完了全程
加特林跑完了全程
鲍威尔跑完了全程
比赛结束

相信已经基本理解了CountDownLatch用法了吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值