老师,countdownlatch 使用意义是什么?为什么要在这里使用这个

来源:5-2 多线程下怎么更新变量值才好

Vali_Lucifer3477978

2020-09-10

写回答

1回答

张勤一

2020-09-11

同学你好:

    课程中我对 CountDownLatch 进行了介绍,但是代码中却没有写出更为详细的注释,这里,我把这段代码贴出来,并给出详细的注释(先去看看这个方法的实现和注释,搞清楚这里面的含义是什么)。

private static void accumulator(int acc) throws Exception {

    // CountDownLatch 其实也被称作是 "倒计时器", 我们这里初始化给定数字 2
    // 即倒计时的个数是 2
    CountDownLatch cdl = new CountDownLatch(2);

    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            for (int j = 0; j < acc; j++) {
                count++;
            }
            // t1 线程倒计时减去 1
            cdl.countDown();
        }
    });
    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            for (int j = 0; j < acc; j++) {
                count++;
            }
            // t2 线程倒计时减去 1
            cdl.countDown();
        }
    });

    // t1 和 t2 线程启动
    t1.start();
    t2.start();

    // 注意, CountDownLatch 的 await 方法会阻塞在倒计时的过程, 只有当倒计时结束之后才会继续向下执行
    cdl.await();

    System.out.println("result = " + count);
}

    既然你说到了 CountDownLatch,我们就先从 CountDownLatch 的构造方法看起:

public CountDownLatch(int count)

    构造方法会传入一个整型数 N,之后调用 CountDownLatch 的 countDown 方法会对 N 减一,知道 N 减到 0 的时候,当前调用 await 方法的线程继续执行。

    CountDownLatch 的方法不是很多,将它们一个个列举出来:

    (1)await() throws InterruptedException:调用该方法的线程等到构造方法传入的 N 减到 0 的时候,才能继续往下执行;

    (2)await(long timeout, TimeUnit unit):与上面的 await 方法功能一致,只不过这里有了时间限制,调用该方法的线程等到指定的 timeout 时间后,不管 N 是否减至为 0,都会继续往下执行;

    (3)countDown():使 CountDownLatch 初始值 N 减 1;

    (4)long getCount():获取当前 CountDownLatch 维护的值;

    那么,如果我们在启动了线程之后,没有 CountDownLatch 的参与,线程执行的很慢,方法会过早的结束,即没有等待其他的线程执行完毕。这样,也就获取不到正确的结果了。

    所以,CountDownLatch 的核心思想是等待其他的任务都执行完成之后,再去执行 “接下来”的事。就像我们的例子中,是主线程等待 t1、t2 结束之后再去执行 System.out 方法。


    我是勤一,致力于将这门课程的问答区打造为 Java 知识体系知识库,Java 知识体系 BBS!共同建造、维护这门课程,我需要每一个你!


4
1
Vali_Lucifer3477978
谢谢老师
2020-09-12
共1条回复

Java实操避坑指南 SpringBoot/MySQL/Redis错误详解

掌握业务开发中各种类型的坑,,Java web开发领域通用

466 学习 · 204 问题

查看课程