当前位置:网站首页>多线程环境下CountDownLatch的用法
多线程环境下CountDownLatch的用法
2022-07-27 14:12:00 【James-Tom】
1、概述
谷歌直译:倒数计时
还有一些其他翻译:计数减小门闩,倒计时闩锁
CountDownLatch类所在的包路径: java.util.concurrent.CountDownLatch
一种同步辅助类,它允许一个或多个线程等待,直到在其他线程中执行的一组操作完成为止。
使用场景:在主线程中创建多个子线程,等待所有子线程执行完成之后,再切换到主线程等待位置并往下继续执行。
2、关键方法、函数
| 名称 | 描述 |
|---|---|
| await() | 导致当前线程等待,直到锁存器递减至零为止,除非该线程被中断。 |
| boolean await(long timeout, TimeUnit unit) | 导致当前线程等待,直到锁存器计数到零为止,除非该线程被中断或经过了指定的等待时间。 |
| countDown() | 减少锁存器的计数,如果计数达到零,则释放所有等待线程。 |
| long getCount() | 返回当前计数。返回值为0时,此后所有等待线程被释放,主线程继续执行await()后的代码。 |
3、案例
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/** * Created by Administrator on 2020/4/24. */
public class TestCountDownLatch {
private static ExecutorService es = Executors.newCachedThreadPool();
static boolean isRun = false;
public static void main(String[] args) {
startTask();
//如果线程池不再使用,可通过下面这句关闭线程池,释放资源。
//es.shutdown();
}
private static volatile CountDownLatch latchInstance;
private static CountDownLatch getInstance(final int count) {
if (null == latchInstance) {
synchronized (CountDownLatch.class) {
if (null == latchInstance) {
latchInstance = new CountDownLatch(count);
}
}
}
return latchInstance;
}
/** * 启动轮询任务 */
private static void startTask() {
int threadNum = 5;
latchInstance = getInstance(threadNum);
for (; ; ) {
//TODO 3、关键语句 为0,则说明所有的子线程执行完成,会执行.await();之后的语句
if (latchInstance.getCount() == 0) {
//latchInstance只能用一次,用完之后变为0 ;为0之后就无法再进行倒计数了,如果要继续倒计数需要重新实例化
latchInstance = null;
//重新实例化时可以设置新的线程数;因为有可能在分组请求场景时,第一组可能只需要5个线程,到了第二轮则只需要3个线程就足够了,节省资源开销。
latchInstance = getInstance(threadNum);
}
if (!isRun) {
isRun = true;
System.out.println("主线程开始执行…… ……");
//在主线程中循环重建threadNum个子线程
for (int i = 0; i < threadNum; i++) {
//往线程池扔子线程
es.execute(() -> {
try {
Thread.sleep(1000);
System.out.println("子线程:" + Thread.currentThread().getName() + "执行");
} catch (InterruptedException e) {
e.printStackTrace();
}
//TODO 1、关键语句 倒计数子线程执行完成情况
latchInstance.countDown();
});
}
try {
//TODO 2、关键语句 这句之后的代码(主线程)会等待所有子线程执行完成后才会继续往下执行。
latchInstance.await();
isRun = false;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(threadNum + "个子线程都执行完毕,继续往下执行主线程 " + isRun);
//第一次,所有子线程执行完成之后,假设:为了节省资源,我将线程数减少到3个。这个地方可以做很多文章,threadNum 是一个动态值,可动态控制子线程数量
threadNum = 3;
}
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
案例中关键的几个地方:
latchInstance.countDown();
子线程完成一个,则计数器-1
latchInstance.await();
这句之后的代码,会等待所有子线程执行完成后,才会继续往下执行,否则一直处于等待状态。
if (latchInstance.getCount() == 0)
如果计数器变为0,则说明所有的子线程执行完成,会执行latchInstance.await();之后的语句
输出:
主线程开始执行…… ……
子线程:pool-1-thread-1执行
子线程:pool-1-thread-3执行
子线程:pool-1-thread-5执行
子线程:pool-1-thread-4执行
子线程:pool-1-thread-2执行
5个子线程都执行完毕,继续往下执行主线程 false
主线程开始执行…… ……
子线程:pool-1-thread-5执行
子线程:pool-1-thread-3执行
子线程:pool-1-thread-4执行
3个子线程都执行完毕,继续往下执行主线程 false
主线程开始执行…… ……
子线程:pool-1-thread-4执行
子线程:pool-1-thread-5执行
子线程:pool-1-thread-3执行
3个子线程都执行完毕,继续往下执行主线程 false
...
案例中通过单例模式来创建CountDownLatch实例。
4、总结
CountDownLatch 在创建实例时构造函数必须要传入一个子线程数量,且子线程数量的值需>0。
当 getCount() =0时,这时候你看到的只是一个普通多线程环境,所以需要重新传入子线程数量创建新CountDownLatch 实例。
边栏推荐
- The interviewer asked: how to judge whether an element is in the visible area?
- @What happens when bean and @component are used on the same class?
- MySQL save data prompt: out of range value for column error
- Graphical SQL is too vivid
- MySQL 面试40连问,面试官你再问下去我可要翻脸了
- 资本频频加码,急于上市的和府捞面有多“疯狂”?
- DXGI 方式采集流程
- 股票买卖4
- 分布式锁
- 【WORK】关于技术架构
猜你喜欢

Why is there no unified quotation for third-party testing fees of software products?

Finally, someone finished all the dynamic planning, linked list, binary tree and string required for the interview

电子制造行业的数字化转型突破点在哪?精益制造是关键

对话框管理器第三章:创建控件

Kotlin的基础用法

Passive income: return to the original and safe two ways to earn

Research on Chinese idiom metaphorical knowledge recognition and relevance based on transfer learning and text enhancement

图解 SQL,这也太形象了吧

Win11壁纸变黑怎么办?Win11壁纸变黑了的解决方法

Research on multi label patent classification based on pre training model
随机推荐
LeetCode 783. 二叉搜索树节点最小距离 树/easy
Stm32f103c8t6 drives sh1106 1.3 "IIC OLED display under Arduino frame
What if win11 wallpaper turns black? The solution of win11 wallpaper blackening
正则表达式:邮箱匹配
网络设备硬核技术内幕 路由器篇 18 DPDK及其前传(三)
网络设备硬核技术内幕 路由器篇 10 CISCO ASR9900拆解 (三)
NEFU118 n! How many zeros are there after [basic theorem of arithmetic]
Regular expressions: mailbox matching
LeetCode 1143. 最长公共子序列 动态规划/medium
Disk troubleshooting of kubernetes node
如何做好企业系统漏洞评估
Visual system design example (Halcon WinForm) -10. PLC communication
网络设备硬核技术内幕 路由器篇 20 DPDK (五)
Construction of knowledge map of financial securities and discovery of related stocks from the perspective of knowledge relevance
谷歌团队推出新Transformer,优化全景分割方案|CVPR 2022
网络设备硬核技术内幕 路由器篇 11 CISCO ASR9900拆解 (五)
Nefu119 combinatorial prime [basic theorem of arithmetic]
[ManageEngine] what is Siem
面试官问:如何判断一个元素是否在可视区域?
Why is there no unified quotation for third-party testing fees of software products?