当前位置:网站首页>多线程并发之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
边栏推荐
- Concatenate strings to get the result with the smallest dictionary order
- Basic usage of Frida
- [kotlin] Introduction to higher-order functions
- Rhcsa Road
- 【Try to Hack】vulnhub DC4
- Chinese diosgenin market forecast and investment strategy report (2022 Edition)
- Research and investment strategy report of China's sodium sulfate industry (2022 Edition)
- Origin2018 installation and use (sorting)
- The difference between the lazy mode of singleton mode and the evil mode
- China BMS battery management system Market Research Report (2022 Edition)
猜你喜欢
Installation and use of sqoop
博睿数据一体化智能可观测平台入选中国信通院2022年“云原生产品名录”
C语言输入/输出流和文件操作
Endeavouros mobile hard disk installation
Rhcsa Road
How to restore the system with one click on Lenovo laptop
你还在用收费的文档管理工具?我这有更牛逼的选择!完全免费
[flask introduction series] cookies and session
[live broadcast appointment] database obcp certification comprehensive upgrade open class
How to solve the keyboard key failure of notebook computer
随机推荐
VMware 虛擬機啟動時出現故障:VMware Workstation 與 Hyper-v 不兼容...
Girls who want to do software testing look here
【C语言基础】12 字符串
独家消息:阿里云悄然推出RPA云电脑,已与多家RPA厂商开放合作
Soft test software designer full truth simulation question (including answer analysis)
Machine learning 11 clustering, outlier discrimination
China carbon disulfide industry research and investment strategy report (2022 Edition)
Chinese diosgenin market forecast and investment strategy report (2022 Edition)
Installation and use of sqoop
Origin2018 installation and use (sorting)
Research and investment strategy report of China's sodium sulfate industry (2022 Edition)
mysql -- explain性能优化
Redis Distributed Lock
Endeavouros mobile hard disk installation
Jojogan practice
How to maintain the laptop battery
How wild are hackers' ways of making money? CTF reverse entry Guide
Please, stop painting star! This has nothing to do with patriotism!
Bugku's file contains
Are you still using charged document management tools? I have a better choice! Completely free