Java 多线程(八)CountDownLatch 同步工具类

35 篇文章 11 订阅

Java 多线程 系列文章目录:


CountDownLatch 是一个同步工具类,用于让一个或多个线程处于等待状态,直到一系列的操作在其他线程执行完毕后。

案例1:主线程等待,直到 3 个线程都执行完毕之后才执行

public class CountDownLatchTest1 {


    private static CountDownLatch countDownLatch = new CountDownLatch(3);

    public static void main(String[] args) throws InterruptedException {

        doSomething();
        doSomething();
        doSomething();

        System.out.println("主线程开始等待...");

        countDownLatch.await();

        System.out.println("主线程开始执行了...");


    }

    private static void doSomething() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " 执行操作需要 3s");
                countDownLatch.countDown();
            }
        }).start();
    }


}

执行结果如下所示:

主线程开始等待...
Thread-1 执行操作需要 3s
Thread-0 执行操作需要 3s
Thread-2 执行操作需要 3s
主线程开始执行了...


接下来,我们再来看一个复杂一点的例子。

案例2:可以将下面的程序理解成:一个裁判和三个运动员之间的关系,比赛之前,裁判在等待运动员就绪,裁判鸣枪后,运动员开始跑,只有等到三个运动员都跑完了,才能宣布成绩。可以用如下程序来实现:

public class CountdownLatchTest2 {
    public static void main(String[] args) {
        ExecutorService service = Executors.newCachedThreadPool();
        // 一个裁判
        final CountDownLatch cdOrder = new CountDownLatch(1);
        // 三个运动员
        final CountDownLatch cdAnswer = new CountDownLatch(3);
        for (int i = 0; i < 3; i++) {
            Runnable runnable = new Runnable() {
                public void run() {
                    try {
                        System.out.println("线程" + Thread.currentThread().getName() + "正准备接受命令");

                        //直到 cdOrder 的计数器归0,才能往下执行
                        cdOrder.await();

                        //如果把这个程序比喻成一个3个运动员在比赛,还有一个裁判
                        //cdOrder的计数器归0,表明裁判鸣枪了,运动员可以跑了.
                        System.out.println("线程"  + Thread.currentThread().getName() + "已接受命令");

                        Thread.sleep((long) (Math.random() * 10000));
                        System.out.println("线程" + Thread.currentThread().getName() + "回应命令处理结果");

                        //每一个运动员到此计数器就减一
                        cdAnswer.countDown();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            service.execute(runnable);
        }
        try {
            Thread.sleep((long) (Math.random() * 10000));

            System.out.println("线程" + Thread.currentThread().getName() + "即将发布命令");

            // cdOrder 的计数器减1,
            cdOrder.countDown();

            System.out.println("线程" + Thread.currentThread().getName() + "已发送命令,正在等待结果");

            // cdAnswer 直到计数器为 0,也就是上面三个线程执行完毕
            cdAnswer.await();

            //裁判就可以公布成绩了
            System.out.println("线程" + Thread.currentThread().getName() + "已收到所有响应结果");

        } catch (Exception e) {
            e.printStackTrace();
        }
        service.shutdown();
    }
}


执行结果如下:


 

 

 

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chiclaim

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值