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免费学习笔记(深入)”;
结合线程池与统计逻辑,构成完整压测骨架
单纯并发不等于压测,还需记录响应时间、成功率、吞吐量等。可这样组织:
- 用 ExecutorService 管理固定数量线程,避免无限制创建
- 每个线程执行:latchReady.countDown() → latchStart.await() → 执行被测方法(如 HTTP 请求)→ 记录耗时/结果到共享容器(如 ConcurrentLinkedQueue 或原子变量)
- 主线程等待所有线程结束(可用 executor.awaitTermination),再汇总统计
注意:不要在多线程里直接操作普通 ArrayList 或 System.out.println,容易干扰测量结果;建议用 ThreadLocal 记录单线程指标,最后合并。
一个小但关键的细节:避免主线程过早退出
如果主线程启动子线程后立刻结束,JVM 可能直接退出,导致压测没跑完就终止。务必确保:
- 主线程调用 executor.shutdown() 后,配合 awaitTermination() 等待任务完成
- 或用 CountDownLatch 等待所有工作线程 run() 结束(适合非线程池场景)
- 加 try-catch 包裹 await(),防止中断异常导致提前退出
不复杂但容易忽略。


















