news 2026/2/23 14:55:46

彻底理解CountDownLatch

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
彻底理解CountDownLatch

CountDownLatch是 Java 并发包(java.util.concurrent)中一个非常经典且实用的同步工具类,由 Doug Lea 设计。它的核心思想是:

让一个或多个线程等待,直到其他线程完成一组操作(“倒计时归零”)后再继续执行。

下面从设计意图、内部实现、使用场景、内存语义四个维度帮你彻底理解它。


一、设计意图:解决什么问题?

场景1:主线程等所有子任务完成

  • 启动 N 个 worker 线程去处理任务。
  • 主线程不能继续,必须等这 N 个都做完。
  • CountDownLatch初始化为 N,每个 worker 完成后调用countDown(),主线程调用await()等待。

场景2:所有线程同时启动(“发令枪”)

  • 所有 worker 线程先启动,但卡在await()
  • 主线程准备就绪后调用countDown()(初始 count=1),所有 worker 同时开始。
  • ✅ 这就是“门闩”(latch)或“栅栏”的作用。

🔑关键特性

  • 一次性(one-shot):计数器只能从 N 减到 0,不能重置
  • 如果你需要重复使用(比如循环等待),请用CyclicBarrier

二、内部实现:基于 AQS 的共享模式

CountDownLatch的核心是内部类Sync,它继承自AbstractQueuedSynchronizer(AQS)。

1. 状态表示

setState(count);// AQS 的 state 字段 = 倒计数值
  • state > 0:还有任务未完成,调用await()的线程要阻塞。
  • state == 0:所有任务完成,所有等待线程被释放。

2. 获取(await)—— 共享模式

protectedinttryAcquireShared(intacquires){return(getState()==0)?1:-1;}
  • 返回1:表示获取成功(可以通行)。
  • 返回-1:表示获取失败(需要排队等待)。
  • 注意:只要state == 0所有调用await()的线程都能立即通过→ 这就是共享模式的体现!

3. 释放(countDown)—— 共享释放

protectedbooleantryReleaseShared(intreleases){for(;;){intc=getState();if(c==0)returnfalse;// 已经归零,无需再释放intnextc=c-1;if(compareAndSetState(c,nextc))returnnextc==0;// 只有归零时才触发唤醒}}
  • 使用 CAS 循环安全地减 1。
  • 只有当nextc == 0时,才返回true,通知 AQS:“现在可以唤醒所有等待者了!”

4. 唤醒机制

  • countDown()使计数归零时,AQS 会调用doReleaseShared()(你之前问过的那个方法)。
  • 因为是共享模式,所有等待线程都会被连续唤醒(传播机制确保不漏掉)。

✅ 所以:CountDownLatch是 AQS共享模式的经典应用


三、典型使用方式(结合你的代码注释)

示例1:发令枪 + 完成信号

CountDownLatchstartSignal=newCountDownLatch(1);// 所有工人等“开始”信号CountDownLatchdoneSignal=newCountDownLatch(N);// 主线程等“完成”信号// 启动 N 个工人for(inti=0;i<N;i++)newThread(()->{startSignal.await();// 阻塞,直到 startSignal.countDown()doWork();doneSignal.countDown();// 完成一个,计数减1}).start();doSomethingElse();// 主线程做准备工作startSignal.countDown();// 发令:所有工人开始!doneSignal.await();// 等待所有工人完成

示例2:并行任务汇总

ExecutorServiceexec=Executors.newFixedThreadPool(4);CountDownLatchlatch=newCountDownLatch(10);for(inti=0;i<10;i++){exec.submit(()->{try{process(i);}finally{latch.countDown();// 必须保证执行!}});}latch.await();// 等待全部10个任务完成exec.shutdown();

⚠️ 注意:countDown()通常放在finally块中,防止异常导致计数不减,造成死锁。


四、内存可见性(Memory Consistency)

Java 内存模型(JMM)保证:

在某个线程调用countDown()之前的所有操作,对在await()成功返回后的线程是可见的。

即:happens-before 关系成立

这意味着:

  • Worker 线程写入的数据(如计算结果到共享变量),
  • 在主线程await()返回后,一定能读到最新值。

✅ 无需额外加volatilesynchronized


五、与 CyclicBarrier 的区别

特性CountDownLatchCyclicBarrier
是否可重用❌ 一次性✅ 可重复使用
触发条件计数归零所有线程到达屏障点
谁等待任意线程(通常是协调者)所有参与线程互相等待
典型用途等待 N 个任务完成 / 发令枪多线程迭代同步(如并行计算每轮同步)

六、总结:一句话理解 CountDownLatch

它是一个“倒计时门闩”:门关着(count > 0),所有想通过的线程(调用 await)都得等着;每有人完成一件事(countDown),计数减一;当计数归零,门打开,所有等待者一拥而过,且之后来的人直接通行。

它的强大之处在于:

  • 简单、高效、线程安全;
  • 利用 AQS 共享模式实现“一对多”或“多对一”的同步;
  • 提供明确的内存可见性保证。

这也是为什么它成为并发编程中的“瑞士军刀”之一。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/17 4:31:29

Free Fs v2.0.0-alpha 已经发布

Free Fs v2.0.0-alpha 作为一次大版本的前置测试版&#xff0c;主要更新聚焦在底层架构优化和功能增强上。本次版本更新亮点下表为你总结了此版本的主要变化&#xff1a;更新类别具体内容与解读存储架构变更移除 MinIO 支持&#xff0c;全面转向 S3 体系。这意味着系统将不再直…

作者头像 李华
网站建设 2026/2/19 2:42:38

GLM-4.6V-Flash-WEB模型在登山路线规划中的图像辅助判断

GLM-4.6V-Flash-WEB模型在登山路线规划中的图像辅助判断多模态AI如何改变户外安全决策&#xff1f; 想象这样一个场景&#xff1a;你正徒步在一条偏僻的山路上&#xff0c;前方路径被碎石覆盖&#xff0c;一侧是陡坡&#xff0c;另一侧植被稀疏。手机信号微弱&#xff0c;地图上…

作者头像 李华
网站建设 2026/2/22 19:27:28

GLM-4.6V-Flash-WEB模型对冻土融化迹象的遥感图像分析

GLM-4.6V-Flash-WEB模型对冻土融化迹象的遥感图像分析 在青藏高原某科研站&#xff0c;研究人员正面对一张来自Sentinel-2卫星的最新遥感图&#xff1a;地表斑驳、水体零散&#xff0c;疑似出现多处热融湖。过去&#xff0c;这样的图像需要数小时的人工判读——比对历史影像、标…

作者头像 李华
网站建设 2026/2/21 23:12:18

开发者必看:如何在实时交互系统中集成GLM-4.6V-Flash-WEB?

开发者必看&#xff1a;如何在实时交互系统中集成GLM-4.6V-Flash-WEB&#xff1f; 你有没有遇到过这样的场景&#xff1a;用户上传一张App界面截图&#xff0c;问“这个按钮是干嘛的”&#xff0c;而你的系统只能靠关键词匹配或预设规则生硬回应&#xff1f;又或者&#xff0c;…

作者头像 李华
网站建设 2026/2/17 6:57:27

GLM-4.6V-Flash-WEB模型在滑翔伞起飞风速判断中的视觉辅助

GLM-4.6V-Flash-WEB模型在滑翔伞起飞风速判断中的视觉辅助在高海拔山脊上&#xff0c;一名滑翔伞飞行员正准备起跑。风从背后推来&#xff0c;但他无法仅凭体感判断这股风是否稳定、方向是否合适——太弱则升力不足&#xff0c;太强或阵发性强则极易失控。传统方式依赖经验与肉…

作者头像 李华
网站建设 2026/2/16 14:02:29

GLM-4.6V-Flash-WEB开源部署指南:单卡推理实现高效多模态应用

GLM-4.6V-Flash-WEB开源部署指南&#xff1a;单卡推理实现高效多模态应用 在当今智能应用快速迭代的背景下&#xff0c;多模态大模型正从“看得见”走向“用得起”。无论是电商平台需要自动识别商品截图中的价格信息&#xff0c;还是客服系统希望理解用户上传的界面问题&#…

作者头像 李华