countdownlatch await 用法

2025年Java面试宝典网盘地址:
🔗 点我获取
提取码:9b3g
什么是CountDownLatch?
CountDownLatch是Java并发包里的一个同步工具类,直译过来叫"倒计时门闩"。它特别适合控制多个线程等待某个共同任务完成的场景。核心思想是:初始化一个计数器,线程调用await()阻塞等待,其他线程完成任务后调用countDown()减少计数,当计数器归零时,所有等待线程被唤醒继续执行。
面试中被问到CountDownLatch的await用法时,一定要抓住它的"多等一"特性——多个线程等待一组操作完成。
await()的核心用法
1️⃣ 基础使用姿势
// 初始化计数器(假设需要等待3个任务)
CountDownLatch latch = new CountDownLatch(3);
// 等待线程调用await()
latch.await(); // 阻塞直到计数器为0
// 工作线程完成任务后减计数
latch.countDown();
2️⃣ 超时控制(面试加分点!)
实际生产环境一定要设置超时时间,避免死等:
boolean success = latch.await(5, TimeUnit.SECONDS);
if(!success) {
// 处理超时逻辑(例如日志告警、中断任务等)
}
3️⃣ 重置陷阱(必考!)
CountDownLatch不能重置!计数器归零后再次调用await()会立即返回。如果需要重复使用,考虑换成CyclicBarrier。
典型面试场景解析
场景1:多线程加载数据后统一处理
"假设你有5个微服务调用,必须全部返回结果才能组装响应,怎么实现?"
答:
用CountDownLatch初始化计数器为5,主线程调用await()阻塞。每个服务线程获取数据后执行countDown()。当计数器归零时,主线程开始组装数据。
场景2:模拟并发压测(秒杀场景)
"如何模拟1千个用户同时发起请求?"
答:
创建CountDownLatch(1000),所有请求线程先调用await()阻塞。主线程调用countDown(1000)瞬间释放所有线程,实现真正并发。
避坑指南(血泪经验)
- 计数器泄露:确保每个
countDown()都被执行(用finally块!) - 线程池搭配陷阱:
executor.execute(()->{ task.run(); latch.countDown(); // 必须放在任务内! }); - 不要和synchronized混用:
await()会释放锁,但synchronized不会!

🛎️ 特别提示:
准备Java面试过程中,如果需要购买面试鸭会员,通过 面试鸭返利网 找我可返利25元!真实优惠,亲测有效 👇
高频面试题
-
Q:
await()和countDown()的调用线程必须相同吗?
A:不需要!这是跨线程通信的工具 -
Q:能在ForkJoinPool中使用吗?
A:谨慎使用!工作窃取机制可能导致countDown()调用次数异常 -
Q:和CyclicBarrier的核心区别?
A:CountDownLatch是事件驱动(任务完成触发),CyclicBarrier是线程同步(线程就绪触发)
掌握这些await用法细节,面试官就知道你真正在项目中用过并发工具了!



