countdownlatch 是 java 并发包中用于协调多线程同步启动的轻量级工具,常用于并发压力测试;推荐用两个 countdownlatch(latchstart 和 latchready)协同实现“全部就绪→统一触发”,配合线程池与线程安全统计完成完整压测骨架。

CountDownLatch 是 Java 并发包中一个轻量级的同步辅助类,非常适合用来协调多个线程在某个“起跑点”同时开始执行,从而模拟真实并发场景,是做并发压力测试的常用工具。
用 CountDownLatch 控制所有线程统一启动
压力测试的关键是让多个线程尽可能在同一时刻发起请求,避免因启动时间差导致结果失真。CountDownLatch 通过一个初始计数器(比如线程总数)和 await()/countDown() 配合,实现“等待全部就绪 → 同时放行”的效果。
- 主线程创建 CountDownLatch(线程数),传给每个工作线程
- 每个工作线程启动后立即调用 latch.await(),进入阻塞状态
- 主线程在启动全部线程后,调用 latch.countDown() —— 实际上只需一次,但更常见的是用另一个 latch 或直接 sleep 后统一触发(见下一点)
推荐结构:两个 CountDownLatch 协同控制
单个 latch 只能做“就绪等待”,无法精准控制“开始时间”。实际压测中建议用两个:
- latchStart:初始值为 1,所有线程 await() 它,表示“等发令枪”
- latchReady:初始值为线程总数,每个线程启动后立刻 countDown(),主线程 await() 它,表示“等所有人准备好”
- 主线程先启动全部线程 → 等 latchReady 计数归零 → 再 countDown(latchStart) → 所有线程瞬间开始执行任务
这样能最大程度减少启动偏差,比简单 for 循环 start() 更可靠。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
结合线程池与统计逻辑,构成完整压测骨架
单纯并发不等于压测,还需记录响应时间、成功率、吞吐量等。可这样组织:
- 用 ExecutorService 管理固定数量线程,避免无限制创建
- 每个线程执行:latchReady.countDown() → latchStart.await() → 执行被测方法(如 HTTP 请求)→ 记录耗时/结果到共享容器(如 ConcurrentLinkedQueue 或原子变量)
- 主线程等待所有线程结束(可用 executor.awaitTermination),再汇总统计
注意:不要在多线程里直接操作普通 ArrayList 或 System.out.println,容易干扰测量结果;建议用 ThreadLocal 记录单线程指标,最后合并。
一个小但关键的细节:避免主线程过早退出
如果主线程启动子线程后立刻结束,JVM 可能直接退出,导致压测没跑完就终止。务必确保:
- 主线程调用 executor.shutdown() 后,配合 awaitTermination() 等待任务完成
- 或用 CountDownLatch 等待所有工作线程 run() 结束(适合非线程池场景)
- 加 try-catch 包裹 await(),防止中断异常导致提前退出
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










