CountDownLatch通过两个倒计时门闩实现线程精准同步起跑:startLatch阻塞所有线程等待主线程发令,doneLatch统计任务完成,配合try-catch、finally及初始化等待确保压测真实并发。

要让多个线程真正“同时起跑”发起请求,不能靠简单地循环启动线程——那样只是顺序创建、调度不可控,实际执行时间错开,测不出真实并发压力。CountDownLatch 的核心价值,就是用一个共享的倒计时门闩,把所有线程卡在临界点,等主线程一声令下,全部放开执行。
为什么普通多线程达不到“同时”效果
线程创建和 CPU 调度存在天然延迟:第 1 个线程可能已开始请求,第 100 个线程还在初始化。这种时间差会让压测结果失真——看起来是 100 并发,实则是“漏斗式”请求流。而 CountDownLatch 提供的是逻辑上的同步栅栏,不依赖系统调度精度,只依赖代码控制时机。
两个 CountDownLatch 配合实现精准起跑
单个 CountDownLatch 只能解决“等待完成”,但压测需要两个阶段控制:
-
startLatch(初始值为 1):所有工作线程调用
await()后阻塞在此,等待主线程调用一次countDown()——这相当于按下“开始”按钮,瞬间释放全部线程 -
doneLatch(初始值为线程总数):每个工作线程执行完任务后调用
countDown();主线程调用await()等待它归零,从而准确统计总耗时与完成状态
关键代码结构要点
避免常见错误,需注意三处细节:
- 工作线程的
await()必须放在try-catch内,且捕获InterruptedException,否则中断信号会丢失 -
countDown()应放在finally块中,确保即使任务抛异常,主线程也不会永远卡在await() - 主线程调用
startLatch.countDown()前,应预留足够时间让所有子线程完成初始化并进入await()状态(例如加 100ms sleep 或用额外信号确认)
可落地的轻量压测模板
不依赖测试框架,几行 Java 就能跑起来:
- 定义线程数(如 200)、构造
startLatch = new CountDownLatch(1)和doneLatch = new CountDownLatch(200) - 每个线程执行前先
startLatch.await(),执行后doneLatch.countDown() - 主线程 sleep 100ms 确保就绪 → 打印“开始”→
startLatch.countDown()→doneLatch.await()→ 输出总耗时 - 单次请求耗时可用
System.nanoTime()记录,比currentTimeMillis()更精确

















