java.util.concurrent.CountDownLatch工具类
CountDown n. 倒数 latch n. 门闩 latch on 占有抓住、理解 one the latch 关着但不上锁
She latch on to your notion. 她理解你的意见。 To open the gate, lift up the latch。要打开大门,先把门闩提起来
CountDownLatch -> 倒数锁存器
CountDownLatch可以看作计数器,同时只能有一个线程去操作计数器也只有一个线程减少这个计数器里面的一个值
public class CountDownLatch extends Object
主要功能: 主线程调用await()实现线程阻塞等待其他线程执行完毕(其他线程执行过程中执行CountDownLatch对象的countDown()方法进行倒计时)。
CountDownLatch类主要方法:
变量和类型 | 方法 | 描述 |
---|---|---|
CountDownLatch(int count) | 构造一个给定计数初始化的CountDownLatch | |
void | await() | 调用await()方法的线程等待直到计数为0 |
void | countDown() | 计数器计数,当计数为0释放所有等待线程 |
long | getCount() | 返回当前计数数字 |
String | toString() | 返回标识锁存器的字符串及其状态 |
应用场景:启动一个服务时,主线程需要等待多个组件加载完毕,之后再继续执行.
🌰实例
/** * @author :Wangzhuang2 * @version : 1.0.0 * @date :Created in 2020/11/10 9:29 * DESC 当前端人员和后端人员完成工作,项目经理宣告项目的开始和结束! */ // 前端人员 class FrontEndStaff implements Runnable{ private CountDownLatch countDownLatch; private String departmentName; FrontEndStaff(CountDownLatch countDownLatch, String departmentName){ this.countDownLatch = countDownLatch; this.departmentName = departmentName; } @Override public void run() { System.out.println("【"+departmentName+"】前端工作开始》》》"); doWork(); try { TimeUnit.SECONDS.sleep(new Random().nextInt(5)); // 慢一点儿 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("【"+departmentName+"】前端界面设计结束!"); this.countDownLatch.countDown(); // 计时器⏲计数 } private void doWork(){ System.out.println("前端界面设计处理中......!"); } } // 后端人员 class BackEndStaff implements Runnable{ private CountDownLatch countDownLatch; private String departmentName; BackEndStaff(CountDownLatch countDownLatch, String departmentName){ this.countDownLatch = countDownLatch; this.departmentName = departmentName; } @Override public void run() { System.out.println("【"+departmentName+"】后端工作开始》》》"); doWork(); try { TimeUnit.SECONDS.sleep(new Random().nextInt(5)); // // 慢一点儿 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("【"+departmentName+"】后端工作结束!"); this.countDownLatch.countDown(); // 计时器⏲计数 } private void doWork(){ System.out.println("后端程序设计和业务实现中..."); } } // 项目经理 class ProjectManager implements Runnable{ private CountDownLatch countDownLatch; ProjectManager(CountDownLatch countDownLatch){ this.countDownLatch = countDownLatch; } @Override public void run() { System.out.println(">>>>项目启动<<<<"); try { this.countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(">>>>项目结束<<<<"); } } public class TestDemo03 { public static void main(String[] args) { CountDownLatch countDownLatch = new CountDownLatch(2); ExecutorService executorService = Executors.newCachedThreadPool(); executorService.execute(new FrontEndStaff(countDownLatch, "前端部门")); executorService.execute(new BackEndStaff(countDownLatch, "后端部门")); executorService.execute(new ProjectManager(countDownLatch)); executorService.shutdown(); } } /* >>>>项目启动<<<< 【后端部门】后端工作开始》》》 【前端部门】前端工作开始》》》 后端程序设计和业务实现中... 前端界面设计处理中......! 【前端部门】前端界面设计结束! 【后端部门】后端工作结束! >>>>项目结束<<<< */
总结
🏳🌈CountDownLatch是一个计数器,计数器的初始值并不一定是线程的数量,完全可以一个线程countDown两次。
🏳🌈所述await种方法阻塞,直到当前计数达到零由于的调用countDown()方法,之后所有等待的线程被释放和任何后续调用await立即返回。 这是一次性现象 - 计数无法重置
学而不思则罔,思而不学则殆!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具