countdownlatch 是 java 压测中实现多线程齐头并发的可靠方式:用一个值为 1 的 startlatch 让所有线程 await 阻塞,主线程 countdown 后同时释放;再用值为并发数的 endlatch 等待全部完成。

在 Java 压测中,要让多个线程“齐头并发”(即同一时刻开始执行任务),CountDownLatch 是最常用且可靠的方式之一。它的核心作用是:让一批线程先阻塞等待,直到一个共享的计数器归零,所有线程才同时释放、开始执行。
初始化 CountDownLatch 控制起跑线
你需要一个 CountDownLatch 实例,初始值设为线程总数(比如 100 个并发线程,就设为 100)。这个 latch 就像发令枪的“预备”信号——所有线程到位后,再统一扣动扳机。
- 在压测主逻辑外创建:
CountDownLatch startLatch = new CountDownLatch(1);(注意:这是“起跑门”,只用 1 个) - 每个工作线程启动后,立刻调用
startLatch.await();进入阻塞,等待发令 - 主线程在所有线程启动完毕后,调用
startLatch.countDown();—— 所有等待线程瞬间唤醒,真正开始压测任务
配合线程池实现可控并发数
不建议直接 new Thread,而是用固定大小的线程池管理,避免资源失控。关键点在于:先提交全部任务,再统一放行。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 用
Executors.newFixedThreadPool(n)创建线程池(n 即目标并发数) - 循环 n 次,向线程池提交 Runnable 任务;每个任务开头就是
startLatch.await() - 等所有任务都已提交(但尚未执行),主线程再触发
countDown() - 这样可确保“几乎同时”开始,误差通常在毫秒级,满足大多数压测场景
加一个结束 latch 等待全部完成
光控制“开始”不够,压测还需知道“什么时候结束”。可以再配一个 CountDownLatch endLatch,用于统计完成数。
- 初始化
endLatch = new CountDownLatch(n) - 每个任务执行完业务逻辑后,调用
endLatch.countDown() - 主线程调用
endLatch.await()阻塞等待全部完成,再打印耗时、汇总结果 - 注意:两个 latch 要分开用,start 控制起点,end 控制终点,职责清晰
完整示例片段(简化版)
以下是一个可直接参考的结构:
int concurrency = 100;
CountDownLatch startLatch = new CountDownLatch(1);
CountDownLatch endLatch = new CountDownLatch(concurrency);
<p>ExecutorService pool = Executors.newFixedThreadPool(concurrency);
for (int i = 0; i {
try {
startLatch.await(); // 等起跑信号
// ✅ 此处放你的压测请求逻辑,如 HTTP 调用、DB 查询等
doRequest();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
endLatch.countDown(); // 完成后计数减一
}
});
}</p><p>long startTime = System.nanoTime();
startLatch.countDown(); // ? 所有线程在此刻放开
endLatch.await(); // 等全部完成
long elapsed = System.nanoTime() - startTime;
System.out.println("总耗时: " + elapsed / 1_000_000.0 + " ms");
pool.shutdown();</p>不复杂但容易忽略:startLatch 只需 1,不是 concurrency;await 和 countDown 的位置决定是否真并发;别忘了异常处理和资源回收。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










