当前位置: 首页 > news >正文

Java CountDownLatch 代码示例:协调多个线程的执行顺序(比赛起跑)

比赛起跑代码详解

代码回顾

importjava.util.concurrent.CountDownLatch;publicclassRaceDemo{publicstaticvoidmain(String[]args)throwsInterruptedException{intrunnerCount=4;CountDownLatchreadyLatch=newCountDownLatch(runnerCount);CountDownLatchstartLatch=newCountDownLatch(1);CountDownLatchfinishLatch=newCountDownLatch(runnerCount);// 运动员线程for(inti=1;i<=runnerCount;i++){intrunnerId=i;newThread(()->{try{// 1. 准备就绪Thread.sleep((long)(Math.random()*1000));System.out.println("运动员"+runnerId+" 准备就绪");readyLatch.countDown();// 2. 等待发令枪响startLatch.await();System.out.println("运动员"+runnerId+" 起跑!");// 3. 跑步Thread.sleep((long)(Math.random()*3000));System.out.println("运动员"+runnerId+" 到达终点");}catch(InterruptedExceptione){e.printStackTrace();}finally{finishLatch.countDown();}}).start();}// 裁判线程readyLatch.await();// 等待所有运动员就绪System.out.println("\n所有运动员准备就绪,比赛开始!\n");Thread.sleep(1000);// 准备时间startLatch.countDown();// 发令枪响finishLatch.await();// 等待所有运动员完成System.out.println("\n比赛结束!");}}

三个 CountDownLatch 的作用

1.readyLatch (准备就绪信号)

CountDownLatchreadyLatch=newCountDownLatch(runnerCount);
  • 用途:确保所有运动员都准备好,裁判才能发令
  • 工作原理
    • 每个运动员准备完成后调用readyLatch.countDown()
    • 裁判调用readyLatch.await()等待所有运动员准备就绪

2.startLatch (发令枪信号)

CountDownLatchstartLatch=newCountDownLatch(1);
  • 用途:控制所有运动员同时起跑(公平性)
  • 工作原理
    • 初始化值为1,所有运动员都在startLatch.await()处等待
    • 裁判调用startLatch.countDown()后,所有等待的运动员同时开始执行

3.finishLatch (完成信号)

CountDownLatchfinishLatch=newCountDownLatch(runnerCount);
  • 用途:等待所有运动员完成比赛
  • 工作原理
    • 每个运动员到达终点后调用finishLatch.countDown()
    • 裁判调用finishLatch.await()等待比赛完全结束

执行流程详解

开始

创建4个运动员线程

运动员各自准备

所有运动员都准备就绪?

裁判宣布: 比赛开始

发令枪响 countDown

运动员同时起跑

运动员各自跑步

所有运动员都到达终点?

宣布比赛结束

阶段一:准备阶段(异步)

运动员1 准备就绪 (readyLatch: 3) 运动员2 准备就绪 (readyLatch: 2) 运动员3 准备就绪 (readyLatch: 1) 运动员4 准备就绪 (readyLatch: 0) → 裁判继续执行

阶段二:起跑阶段(同步)

裁判: 所有运动员准备就绪,比赛开始! 裁判: 准备时间1秒... 裁判: 发令枪响!(startLatch.countDown()) 所有运动员同时: 起跑!

阶段三:比赛阶段(异步)

运动员3 到达终点 (finishLatch: 3) 运动员1 到达终点 (finishLatch: 2) 运动员4 到达终点 (finishLatch: 1) 运动员2 到达终点 (finishLatch: 0) → 比赛结束

关键点解释

为什么用 startLatch(1)?

CountDownLatchstartLatch=newCountDownLatch(1);
  • 只需要一个信号(裁判开枪)就能释放所有等待的运动员
  • 确保绝对的公平:所有运动员在同一时刻收到起跑信号

时间随机性的作用

Thread.sleep((long)(Math.random()*1000));// 准备时间不同Thread.sleep((long)(Math.random()*3000));// 跑步速度不同
  • 模拟现实:运动员准备速度和跑步速度都不同
  • 可以看到:准备快的运动员不一定跑得最快

实际输出示例

运动员2 准备就绪 运动员1 准备就绪 运动员4 准备就绪 运动员3 准备就绪 所有运动员准备就绪,比赛开始! 运动员2 起跑! 运动员1 起跑! 运动员4 起跑! 运动员3 起跑! 运动员2 到达终点 运动员4 到达终点 运动员1 到达终点 运动员3 到达终点 比赛结束!

实际应用场景

这种模式适用于:

  1. 分布式系统启动:等待所有服务就绪后再对外提供服务
  2. 性能测试:准备多个压测线程,同时发起请求
  3. 游戏服务器:等待所有玩家加载完成后再开始游戏
  4. 数据计算:等待所有数据分片处理完成再汇总结果

扩展思考

如果要增加功能,比如:

  • 抢跑检测:可以在startLatch.await()前添加检查
  • 中途退赛:异常情况下也需要调用finishLatch.countDown()
  • 成绩排名:需要收集每个运动员的完成时间

这个示例完美展示了 CountDownLatch 如何协调多个线程的执行顺序,是并发编程中的经典模式。

http://www.jsqmd.com/news/172971/

相关文章:

  • 电气设备的发热量计算
  • 试过很多方法没用!怎么让孩子近视度数涨得慢些?
  • Segmentation Fault 调试指南:gdb + ASan + Valgrind 全流程实战
  • 微网优化调度:Matlab + Yalmip 实现之旅
  • 荣膺行业殊荣,iBox以数字科技激活文化传承新生态
  • MATLAB + 深度学习 = 心电图分类神器!完整流程 + 关键代码
  • 北京陪诊机构推荐守嘉陪诊:全链条护航让首都就医更从容 - 品牌排行榜单
  • 2025最新!自考党必看!10个AI论文平台测评与推荐
  • 不止是整理
  • UKB数据库/RAP平台批量下载数据教程
  • javaSE继承随笔
  • 做好孩子视力守护者预防“小眼镜”秘籍在这里
  • 智能一卡通系统配置清单包含管理中心设备、门禁、考勤、访客、通道闸机、梯控、停车场等九大子系统。核心设备包括服务器、管理平台、读卡器等,各子系统通过统一平台实现数据交互与权限管理
  • 云服务器 vs 传统服务器:核心区别与选型指南​
  • 云服务器成本管控:从粗放投入到精细运营
  • 智慧指挥中心建设厂商重磅盘点,成功案例+专业背书,itc保伦股份值得信赖 - 速递信息
  • Java+React全栈开发面试宝典(完整60题)
  • 云服务器架构演进:从虚拟化到容器化与无服务器的跨越
  • 云服务器架构演进:从虚拟化到容器化与无服务器的跨越
  • 2026年AI入门指南:四个学习平台的使用体验 - 速递信息
  • 墨香飘洋:当外国友人执起中国毛笔
  • 基于微信小程序的课程资料共享平台设计与实现
  • 回收站存在大量对象,导致Insert into...select语句夯住
  • 重磅签约!上海比孚携手 Dify,让企业 AI Agent 开发更简单、价值落地更高效
  • docker部署elk+filebeat日志收集分析系统
  • 科研牛马千万不要错过!手把手教你用AI精准匹配真实参考文献,仅需一个专业应用+两个提示词指令
  • 云服务器运维实战:从环境搭建到安全加固全流程​
  • iBox CEO宣松涛畅谈数字文创破局之道
  • Nginx 站点垂直扩容(单机性能升级)全攻略
  • CCF-GESP计算机学会等级考试2025年12月三级C++T2 小杨的智慧购物