当前位置:网站首页>多线程并发之CountDownLatch阻塞等待
多线程并发之CountDownLatch阻塞等待
2022-07-01 16:33:00 【鱼找水需要时间】
1. 简介
CountDownLatch中count down是倒数的意思,latch则是门闩、锁住的含义。整体含义可以理解为倒数的门栓。CountDownLatch的作用也是如此,在构造CountDownLatch的时候需要传入一个整数n(必须>0),在这个整数“倒数”到0之前,主线程需要等待在门口,而这个“倒数”过程则是由各个执行线程驱动的,每个线程执行完一个任务“倒数”一次。总结来说,CountDownLatch的作用就是等待其他的线程都执行完任务,必要时可以对各个任务的执行结果进行汇总,然后主线程才继续往下执行。
CountDownLatch主要有两个方法:countDown()和await()。countDown()方法用于使计数器减一,其一般是执行任务的线程调用,await()方法则使调用该方法的线程处于等待状态,其一般是主线程调用。这里需要注意的是,countDown()方法并没有规定一个线程只能调用一次,当同一个线程调用多次countDown()方法时,每次都会使计数器减一;另外,await()方法也并没有规定只能有一个线程执行该方法,如果多个线程同时执行await()方法,那么这几个线程都将处于等待状态,并且以共享模式享有同一个锁。
2. 方法API
方法:
| 方法 | 说明 |
|---|---|
| await() | 使当前线程进入同步队列进行等待,直到latch的值被减到0或者当前线程被中断,当前线程就会被唤醒。 |
| await(long timeout, TimeUnit unit) | 等待timeout时间后,count的值还不是0,不再等待,那么将继续执行 |
| countDown() | 使latch的值减1,如果减到了0,则会唤醒所有等待在这个latch上的线程。 |
| getCount() | 获得latch的数值。 |
3. 使用
3.1 await()
示例:
CountDownLatch count = new CountDownLatch(3);
new Thread(()->{
//处理业务1
try {
TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) {
e.printStackTrace(); } finally {
count.countDown();//确保每个任务执行完递减
}
}, "t1").start();
new Thread(()->{
//处理业务2
try {
TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) {
e.printStackTrace(); } finally {
count.countDown();//确保每个任务执行完递减
}
}, "t2").start();
new Thread(()->{
//处理业务3
try {
TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) {
e.printStackTrace(); } finally {
count.countDown(); //确保每个任务执行完递减
}
}, "t3").start();
long startTime = System.currentTimeMillis();
count.await(); // 等待任务执行
long endTime = System.currentTimeMillis();
System.out.println("任务执行完成,耗时:" + (endTime - startTime) + "毫秒");
结果:

3.2 boolean await(long timeout, TimeUnit unit)
boolean await(long timeout, TimeUnit unit)示例:
CountDownLatch count = new CountDownLatch(3);
new Thread(()->{
//处理业务1
try {
TimeUnit.SECONDS.sleep(1);
System.out.println("task1 over");} catch (InterruptedException e) {
e.printStackTrace(); } finally {
count.countDown();//确保每个任务执行完递减
}
}, "t1").start();
new Thread(()->{
//处理业务2
try {
TimeUnit.SECONDS.sleep(2);
System.out.println("task2 over");} catch (InterruptedException e) {
e.printStackTrace(); } finally {
count.countDown();//确保每个任务执行完递减
}
}, "t2").start();
new Thread(()->{
//处理业务3
try {
TimeUnit.SECONDS.sleep(3);
System.out.println("task3 over");} catch (InterruptedException e) {
e.printStackTrace(); } finally {
count.countDown(); //确保每个任务执行完递减
}
}, "t3").start();
long startTime = System.currentTimeMillis();
boolean await = count.await(2, TimeUnit.SECONDS);// 指定等待时间,如果当前有任务未执行完成则返回false
System.out.println("所有任务是否执行完成:" + (await ? "是" : "否"));
System.out.println("计数器值为:" + count.getCount());
long endTime = System.currentTimeMillis();
System.out.println("任务执行完成,耗时:" + (endTime - startTime) + "毫秒");
分析:
开启三个线程去执行任务,任务1、任务2、任务3耗时依次为1s、2s、3s
计数器await等待2s,如果2s后计数器值不为0(即三个任务中有任务未执行完成),那么就返回false。可以用在一些比较耗时长的任务上,例如调用第三方接口、业务线比较长,当超过指定时间后就当作失败处理,避免服务一直处于等待阻塞状态。
结果:

4. CountDownLatch和Thread.join()方法的区别
1、
CountDownLatch的作用就是允许一个或多个线程等待其他线程完成操作,看起来有点类似join()方法,但其提供了比join()更加灵活的API。2、
CountDownLatch可以手动控制在n个线程里调用n次countDown()方法使计数器进行减一操作,也可以在一个线程里调用n次执行减一操作。 而join()的实现原理是不停检查join线程是否存活,如果join线程存活则让当前线程永远等待。所以两者之间相对来说还是CountDownLatch使用起来较为灵活。
5. CountDownLatch的不足
CountDownLatch是一次性的,计算器的值只能在构造方法中初始化一次,之后没有任何机制再次对其设置值,当CountDownLatch使用完毕后,它不能再次被使用。
6. 扩展
如果采用多线程异步任务Future,通过CompletableFuture.allOf也可以实现同样的效果,阻塞等待任务执行结果,参考文章多线程Future,CompletableFuture
边栏推荐
- Report on Market Research and investment prospects of ammonium dihydrogen phosphate industry in China (2022 Edition)
- Redis distributed lock
- 如何写出好代码 — 防御式编程指南
- Tutorial on principles and applications of database system (004) -- MySQL installation and configuration: resetting MySQL login password (Windows Environment)
- Mlperf training v2.0 list released, with the same GPU configuration, the performance of Baidu PaddlePaddle ranks first in the world
- String class
- 博睿数据一体化智能可观测平台入选中国信通院2022年“云原生产品名录”
- How to use F1 to F12 correctly on laptop keyboard
- AI college entrance examination volunteer filling: the gods of Dachang fight, and candidates pay to watch
- Transition technology from IPv4 to IPv6
猜你喜欢

Tutorial on the principle and application of database system (002) -- MySQL installation and configuration: MySQL software uninstallation (Windows Environment)
![[JetsonNano] [教程] [入门系列] [三] 搭建TensorFlow环境](/img/0e/52e37527bc717c7a55741725087bad.png)
[JetsonNano] [教程] [入门系列] [三] 搭建TensorFlow环境

SQL question brushing 584 Looking for user references

How to restore the system with one click on Lenovo laptop

Kali install Nessus

Hi Fun Summer, play SQL planner with starrocks!

SQL question brushing 627 Change gender

Basic usage of Frida

Mlperf training v2.0 list released, with the same GPU configuration, the performance of Baidu PaddlePaddle ranks first in the world

Jojogan practice
随机推荐
MySQL learning summary
Tutorial on the principle and application of database system (005) -- Yum offline installation of MySQL 5.7 (Linux Environment)
sql刷题627. 变更性别
SQL question brushing 1050 Actors and directors who have worked together at least three times
Report on Market Research and investment prospects of ammonium dihydrogen phosphate industry in China (2022 Edition)
Preliminary study on golang crawler framework
【C语言补充】判断明天是哪一天(明天的日期)
Zabbix2.2 monitoring system and application log monitoring alarm
Detailed explanation of activity life cycle and startup mode
Girls who want to do software testing look here
Tutorial on principles and applications of database system (004) -- MySQL installation and configuration: resetting MySQL login password (Windows Environment)
Exclusive news: Alibaba cloud quietly launched RPA cloud computer and has opened cooperation with many RPA manufacturers
博睿数据一体化智能可观测平台入选中国信通院2022年“云原生产品名录”
【PyG】文档总结以及项目经验(持续更新
Is it reliable to open an account on flush with mobile phones? Is there any potential safety hazard
软件工程导论——第六章——详细设计
VMware 虚拟机启动时出现故障:VMware Workstation 与 Hyper-v 不兼容...
求求你们,别再刷 Star 了!这跟“爱国”没关系!
数据库系统原理与应用教程(005)—— yum 离线安装 MySQL5.7(Linux 环境)
Ring iron pronunciation, dynamic and noiseless, strong and brilliant, magic wave hifiair Bluetooth headset evaluation