面试鸭返利网

countdownlatch 使用方式

CountDownLatch是Java多线程编程中的核心同步工具,面试高频考点!它通过计数器机制实现主线程等待多个子线程完成,常用于任务分片、服务启动依赖等场景。本文详细解析CountDownLatch的4步使用法:初始化计数器、子线程countDown()、主线程await()、状态检查,并提供大数据处理和微服务启动等实战案例。对比CyclicBarrier和Semaphore的区别,总结常见面试题及避坑指南,如异常处理和性能优化。附赠2025年Java面试题库下载,助你轻松应对多线程面试难题!想获取更多面试资料可访问面试鸭返利网。

CountDownLatch 使用方式

作为程序员,面试被问“CountDownLatch 怎么用?”简直家常便饭。今天咱就掰开揉碎讲明白,让你面试直接拿分!

附:2025年Java面试高频题合集
🔗 链接: https://pan.baidu.com/s/1RUVf75gmDVsg8MQp4yRChg?pwd=9b3g
提取码: 9b3g


一、CountDownLatch 是干啥的?

简单说,它就是个线程协调工具。想象你组队打副本:5个队友必须全部到齐,队长才能开团。CountDownLatch 就是这个“队长”——它用数字倒计时卡住主线程,直到所有子线程完成任务。

CountDownLatch多线程协作
(多线程任务协调示意图)


二、核心使用方式四步走

面试官最想听你理清逻辑,直接上步骤:

步骤1:初始化倒计数器

CountDownLatch latch = new CountDownLatch(3); // 参数3=需要3个线程完成任务 

这里数字代表需要等待的线程数量,比如要等3个文件下载完再合并。

步骤2:子线程调用 countDown()

每个线程完成任务后调用:

public void run() { 
    // ... 执行下载任务 
    latch.countDown(); // 倒计时-1 
} 

关键点countDown()要放在 finally 块!避免线程异常导致主线程死等。

步骤3:主线程调用 await()

主线程在需要阻塞的地方“蹲守”:

latch.await(); // 卡在这里,直到计数器归零 
// 所有线程完成后,继续执行合并文件 

支持超时机制:await(10, TimeUnit.SECONDS) 防止死锁。

步骤4:检查计数器状态

通过getCount()查看剩余任务数,调试时很有用。


三、经典面试场景举例

场景1:大数据分片处理

“我有100W数据切分10份,10个线程并行处理,全部处理完再入库。”

CountDownLatch latch = new CountDownLatch(10); 
for(int i=0; i<10; i++){ 
    new Thread(() -> { 
        processData(); 
        latch.countDown(); 
    }).start(); 
} 
latch.await(); 
saveToDB(); // 确保所有分片处理完才执行 

场景2:服务启动依赖检查

“支付服务启动前,必须确认账户服务、风控服务、日志服务都就绪。”
服务启动依赖


四、避坑指南(面试加分项!)

  1. 复用问题
    CountDownLatch 倒计时到0后就不能重置了!想循环用?选 CyclicBarrier
  2. 异常处理
    子线程异常时一定要在finally中调用countDown(),否则主线程永远阻塞。
  3. 性能陷阱
    线程数别设置太大(比如10W+),await()会竞争锁,影响性能。

五、对比其他同步工具

| 工具 | 特点 | 适用场景 |
|---------------------|------------------------------|--------------------------|
| CountDownLatch | 一次性的,主等子 | 启动依赖、分批任务汇总 |
| CyclicBarrier | 可重置的,子等子 | 分阶段并行计算 |
| Semaphore | 控制资源并发量 | 数据库连接池限流 |


六、高频面试题(附解题思路)

Q:CountDownLatch 和 join() 有什么区别?

A:join() 只能等单个线程,CountDownLatch 能灵活控制多个线程,还能设置超时!

Q:计数器为0后,再调用 await() 会怎样?

A:立刻放行!因为此时计数器已经是0了,不会阻塞。

Q:子线程还没执行完,主线程就继续了,可能是什么原因?

A:大概率是latch.countDown()被提前调用了,比如在子线程开头就写了。


💡 小贴士:若想获取最新Java面试题库或面试鸭会员优惠,可访问 面试鸭返利网。通过该站联系我,购买会员可返利 25 元
面试鸭返利优惠

(小提示:实际开发中,CompletableFuture 处理异步任务更灵活,但面试必问 CountDownLatch!)

如果你想获取更多关于面试鸭的优惠信息,可以访问面试鸭返利网面试鸭优惠网,了解最新的优惠活动和返利政策。

立即加入面试鸭会员 →