CountDownLatch小记

过年后,懒惰小人总是能够轻而易举地击败那个可怜的勤奋小人,转眼间又有好几周没有写文章了。愧疚感满满,作出检讨,主要原因:

第一,工作忙,重构任务重;
第二,人到中年,开始养生,没想到这还真是一个需要花时间的事情。
第三,有时会去偷看《风味人间》和《圆桌派》,怪我咯!谁叫人家的节目做的那么好看。

接着,分享一个最近看文章养成的习惯:

第一,先大体扫读一遍,看看评论好坏和文章排版,基本上就能知道这篇文章讲的水平与深度是否值得去读;
第二,接着一字一句慢慢读,不要求快,容易遗漏关键信息。
第三,变读边想,由文章所描述的内容可以推出什么其他信息或问题。

好了,言归正传。今天在学习网络编程时,接触到一个类,计数锁CountDownLatch类,以前竟然没有发现这个这么好用的同步工具类,还自己去傻傻的实现过同样的功能。

1 简介

对于这个类,最常用的场景就是等待前面n个任务完成,然后再去执行另外一个任务。

这个场景,用在我们项目中的接口上最合适不过了,我们的APP中同一个页面经常需要调用好几个接口去拼装数据。把这些接口串联起来有可能因为其中的一个接口出现异常而导致数据刷新失败。回来一个接口就去刷新一个数据总显得又不是那么优雅。

2 CountDownLatch的使用

而CountDownLatch的使用将很方便的解决上述问题,我们一起来看看。

初始化CountDownLatch,2为内部的计数值,代表可以调用几次countDown()方法。每次调用都会递减内部的计数值,当为0时,await()方法所等待的线程将被唤醒。

初始化
CountDownLatch latch = new CountDownLatch(2);

计数值减1
latch.countDown();

让某个线程进行等待,直到计数值变成0为止。
latch.await();

接着我们上代码。

CountDownLatch latch = new CountDownLatch(2);

CheckThread checkNet = new CheckThread("net", latch);
CheckThread checkApp = new CheckThread("app", latch);

new Thread(() -> {
    System.out.println("await thread is begin!");
    try {
        latch.await();
        System.out.println("await thread is done!");

    } catch (InterruptedException e) {
        e.printStackTrace();
    }

}).start();

checkApp.start();
checkNet.start();


class CheckThread extends Thread {
    private String name;
    private CountDownLatch latch;

    CheckThread(String name, CountDownLatch latch) {
        this.name = name;
        this.latch = latch;
    }

    @Override
    public void run() {
        super.run();
        System.out.println("任务" + name + "开始运行");

        try {
            sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (latch != null) {
                latch.countDown();
            }
        }

        System.out.println("任务" + name + "完成");

    }
}

我们初始化了两个线程checkNet,checkApp去执行耗时任务,当任务结束时,我们调用countDown()方法表示该条线程处的任务执行完毕。

我们可以把线程checkNet,checkApp分别看成接口A和接口B去请求数据,而new Thread()产生的线程则一直在等待其他两条线程执行结束,如果结束,new Thread()线程将被唤醒,继续执行余下的逻辑。

这里的new Thread()线程的开启是为了在Android中不阻塞主线程,它的等待也可以用如下方式设置最多等到多久

latch.await(10, TimeUnit.SECONDS);

以免某个线程没有正确返回导致一直处于等待中。

最终打印的结果如下

await thread is begin!
任务app开始运行
任务net开始运行
任务net完成
任务app完成
await thread is done!

Process finished with exit code 0

欢迎留言交流,如果觉得有用,请点赞支持!

你可能感兴趣的:(CountDownLatch小记)