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

CountDownLatch 实现精准的并发控制

CountDownLatch 实现精准的并发控制

概述

本文档详细分析并发启动场景(赛跑模式)中两个 CountDownLatch 的作用和阻塞关系。


代码示例

importjava.util.concurrent.CountDownLatch;publicclassRaceStartDemo{publicstaticvoidmain(String[]args)throwsInterruptedException{finalintrunnerCount=10;finalCountDownLatchreadyLatch=newCountDownLatch(runnerCount);// 计数器=10finalCountDownLatchstartLatch=newCountDownLatch(1);// 计数器=1// 启动10个运动员线程for(inti=0;i<runnerCount;i++){finalintid=i;newThread(()->{try{System.out.println("运动员 "+id+" 准备就绪");readyLatch.countDown();// ← 不阻塞,只是计数-1startLatch.await();// ← 阻塞的是运动员线程!System.out.println("运动员 "+id+" 起跑!");}catch(InterruptedExceptione){e.printStackTrace();}}).start();}// 主线程(裁判)readyLatch.await();// ← 阻塞的是主线程!System.out.println("\n所有运动员就位,准备发令!");Thread.sleep(500);startLatch.countDown();// ← 主线程执行,唤醒所有运动员System.out.println("砰!");}}

两个 Latch 对比

Latch谁调用 await()阻塞的是谁谁调用 countDown()初始计数作用
readyLatch主线程主线程各个 Runner 线程10主线程等待所有运动员就位
startLatchRunner 线程Runner 线程主线程1运动员等待发令枪

执行流程图

┌─────────────────────────────────────────────────────────────┐ │ Phase 1: 准备阶段 │ ├─────────────────────────────────────────────────────────────┤ │ Runner-1: readyLatch.countDown() (不阻塞) readyLatch: 10→9 │ │ Runner-2: readyLatch.countDown() (不阻塞) readyLatch: 9→8 │ │ ... │ │ Runner-10: readyLatch.countDown() (不阻塞) readyLatch: 1→0 │ │ │ │ 主线程: readyLatch.await() ←─────── 阻塞主线程! │ │ 等待 readyLatch 从 10 减到 0 │ └─────────────────────────────────────────────────────────────┘ ↓ readyLatch == 0 主线程被唤醒 ┌─────────────────────────────────────────────────────────────┐ │ Phase 2: 起跑阶段 │ ├─────────────────────────────────────────────────────────────┤ │ Runner-1: startLatch.await() ←─────── 阻塞运动员线程! │ │ Runner-2: startLatch.await() ←─────── 阻塞运动员线程! │ │ ... │ │ Runner-10: startLatch.await() ←────── 阻塞运动员线程! │ │ │ │ 主线程: startLatch.countDown() startLatch: 1→0 │ │ (发令枪!) │ └─────────────────────────────────────────────────────────────┘ ↓ startLatch == 0 所有运动员线程被唤醒,开始跑!

形象类比:赛跑场场景

🏁 赛跑场场景 🏃‍♂️ Runner-1 🏃‍♂️ Runner-2 🏃‍♂️ Runner-10 │ │ │ │准备就绪 │准备就绪 │准备就绪 ▼ ▼ ▼ countDown() countDown() countDown() (报到) (报到) (报到) 👨‍💼 裁判(主线程) │ readyLatch.await() │ ⏳ 等待中... (所有人都报到了,readyLatch == 0) │ startLatch.countDown() ←─── 砰!发令枪 ────→ │ 所有 Runner 被唤醒,开始跑!

详细时间线

时间轴 → T0: 主线程启动 10 个 Runner 线程 T1: Runner-1 执行 readyLatch.countDown() (readyLatch: 10→9) T2: Runner-2 执行 readyLatch.countDown() (readyLatch: 9→8) ... T10: Runner-10 执行 readyLatch.countDown() (readyLatch: 1→0) T11: 主线程的 readyLatch.await() 返回!主线程继续执行 T12: 主线程打印 "所有运动员就位,准备发令!" T13: 主线程 sleep 500ms T14: 主线程执行 startLatch.countDown() (startLatch: 1→0) T15: 所有阻塞在 startLatch.await() 的 Runner 线程被唤醒! T16: 所有 Runner 开始跑

关键点总结

❌ 常见误解

错误理解:两个 Latch 阻塞的都是主线程

✅ 正确理解

Latch阻塞的线程谁来唤醒
readyLatch主线程Runner 线程们(通过 countDown)
startLatchRunner 线程们主线程(通过 countDown)

为什么需要两个 Latch?

只用一个 CountDownLatch 无法实现这种精确的同步:

  • 只用 readyLatch:主线程可以等待运动员就位,但无法控制运动员同时起跑
  • 只用 startLatch:运动员可以等待发令枪,但主线程不知道运动员是否都准备好了

双 Latch 设计实现了:

  1. 确保所有运动员都就位后,裁判才发令
  2. 确保所有运动员同时收到发令信号,公平起跑

适用场景

这种双 Latch 模式适用于:

  • ✅ 需要多个线程同时启动的场景
  • ✅ 需要主线程确认所有子线程准备就绪
  • ✅ 需要精确控制并发开始时机
  • ✅ 批量任务并行执行,要求同时开始

与 CyclicBarrier 的对比

特性CountDownLatch(双 Latch)CyclicBarrier
等待方向互为依赖(互相等待)所有线程互相等待
重用性不可重用可循环使用
线程数量主线程 + 子线程所有线程地位平等
典型场景主控并发并行计算分阶段

总结

核心要点

  1. readyLatch 阻塞主线程:主线程等待所有子线程准备就位
  2. startLatch 阻塞子线程:子线程等待主线程发令
  3. 互相等待:实现精确的并发控制
  4. 一次性使用:CountDownLatch 计数归零后无法重置

阻塞关系速记

┌─────────────┐ ┌─────────────┐ │ 主线程 │────────▶│ readyLatch │ 阻塞主线程 │ (裁判) │ └─────────────┘ └─────────────┘ ▲ │ │ Runner 线程们 │ countDown() │ ┌─────────────┐ ┌─────────────┐ │ Runner们 │◀────────│ startLatch │ 阻塞 Runner 们 │ (运动员) │ └─────────────┘ └─────────────┘ ▲ │ │ 主线程 │ countDown()(发令枪)

总结:readyLatch 让裁判等待运动员,startLatch 让运动员等待裁判。

http://www.cnnetsun.cn/news/3150778.html

相关文章:

  • 商用烤盘定制厂家正规机构
  • 从 OC 平滑迁移 Swift 完整方案
  • VIbe Coding时期,推送项目惹众宾欢也
  • 小红书数据采集终极指南:Python xhs库完整实战教程
  • DeepSeek API 零基础接入指南:从 VS Code 插件到命令行调用
  • python神经网络编程入门(一)—— 分类器
  • 另类手搓大模型
  • 正版terraria怎么联机,正版terraria要怎么和朋友联机
  • 佛得角能够进入世界杯16强给我们的启示
  • 用运筹学与强化学习构建个人发展量化分析模型
  • 【全网最详细】Inventor 2027下载免费版 Inventor三维机械设计软件安装图解(2026最新)
  • 通信原理振幅调制解调电路仿真实操记录
  • USART通信详解:USART和UART区别、异步/同步模式、8N1、状态标志与调试方法
  • RAG 工程化实践:如何避免半成品文档进入在线召回
  • 微信 Dat 文件逆向分析:从 0x17CE 文件头到 PNG 图片的 3 步解密实战
  • 一次 Agent Run 是怎么发生的:从用户目标到工具调用、状态更新和风险拦截
  • STM32与H桥驱动芯片实现直流有刷电机高性能控制
  • 电机控制到底要学哪些东西?它不是一门课,而是一个交叉工程系统
  • 基于Codex与Claude的学术技能包:自动化科研工作流全解析
  • stortrace可视化分析:如何解读IO延迟热力图和时序图
  • 小米寥寥几家车企设计汽车顶棚
  • 速卖通商品信息自动翻译实现方案
  • 2026年AI论文软件测评:5款神器从大纲到答辩全链路通关攻略
  • 2026年靠谱AI论文软件全攻略(含保姆级操作教程)
  • WasmVideoPlayer:浏览器里直接播放H265视频
  • GitHub功能全览:含AI代码创作、多解决方案及汽车故障诊断音频ML项目
  • 性价比高的区域教育一体化管理平台哪个更完善
  • 云原生技术28-K8s排障实战:20个常见问题的快速定位与解决,从CrashLoopBackOff到Running的完整指南
  • SSTImap实战指南:自动化检测与利用服务器端模板注入漏洞
  • 2025年AI Agent爆发:程序员转型“智能体指挥官“的5个实战路径