CountDownLatch介绍及使用

CountDownLatch作用阻塞一个或多个线程等待其他线程完成操作。

定义初始化的时候,需要传入一个正数来初始化计数器(0也可以,但这样定义没有实际意义)。有两个方法countDown()用于递减计数器,await()方法阻塞当前线程,直到计数器递减为0

CountDownLatch通常用于多个线程之间的协调工作。

假设有如下情节:

同时获取5张表的数据并一同返回

为了让cpu更好的得到利用,程序执行效率更高,使用多线程来完成。

看如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class CountDownLatchExample {
// 循环次数
private static final int FOR_NUMBER = 5;


public static void main(String[] args) {

// 查询数据
for (int i = 0; i < FOR_NUMBER; i++) {
new Thread(() -> {
System.out.println("查询第:\t" + Thread.currentThread().getName() + "张表数据完成!");
}, String.valueOf(i)).start();
}


System.out.println("查询完毕");

}
}

我们看一下执行结果是否是我们想要的结果。

image-20200105175835144

可以看到,还有数据没查询完成他就体检进行查询完毕的操作了。那如果在实际开发过程中,就等于数据还没处理完成就返回用户数据了。这并不是我们想要的结果。

那么刚才也有说CountDownLatch是阻塞一个或多个线程等待其他线程完成操作,那么我们试一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class CountDownLatchExample {
// 循环五次
private static final int FOR_NUMBER = 5;

// 实例化定义一个CountDownLatch需要减少的总次数
private static CountDownLatch countDownLatch = new CountDownLatch(5);


public static void main(String[] args) {

// 查询数据
for (int i = 0; i < FOR_NUMBER; i++) {
new Thread(() -> {
System.out.println("查询第:\t" + Thread.currentThread().getName() + "张表数据完成!");

// 执行完 查询 然后进行递减操作 每次减1
countDownLatch.countDown();
}, String.valueOf(i)).start();
}

try {
countDownLatch.await(); // await()方法起到阻塞的作用,直到计数器值等于0
} catch (InterruptedException e) {
e.printStackTrace();
}


System.out.println("查询完毕");

}
}

上边我们定义了一个CountDownLatch里边值写入的是5表明我们总共需要减少的次数,再每次执行完查询操作完成后进行减1操作,最后在执行完毕之前进行await()方法阻塞,计数器为0则才放过往下走。我们看一下就结果是否跟想象的一样。

image-20200105180700120

OKK!非常完美的达到了预期的效果。

总体CountDownLatch的作用以及使用就没有了,很简单,大家可以多多尝试。在开发中用到非常多。

补充:

CountDownLatchawait()有重载方法await(long timeout, TimeUnit unit), timeout则是设置最大等待时间,unit则是时间类型,如果超过这个时间程序则将继续执行,不再阻塞。

喜欢关注公众号:

qrcode

评论

You forgot to set the shortname for Disqus. Please set it in _config.yml.