CountDownLatch的使用
作为程序员,面试时被问到“CountDownLatch怎么用?”简直是高频送分题!今天咱们就掰开揉碎聊聊这个同步工具的精髓,让你在面试中游刃有余。

📥 最新面试资料分享:
👉 2025年Java面试宝典网盘下载(提取码:9b3g)
🔍 什么是CountDownLatch?
简单说就是个计数器锁!初始化时设定一个数值(比如N),主线程调用await()会阻塞,直到其他N个线程通过countDown()把计数器减到0。这种多线程协同的模型,特别适合“等所有人到齐再发车”的场景。
⚙️ CountDownLatch的核心使用步骤
- 创建实例:
CountDownLatch latch = new CountDownLatch(3);// 初始计数值=3 - 子线程完成任务后计数减1:
// 在每个子线程中执行 latch.countDown(); // 调用后计数器-1 - 主线程等待所有任务完成:
latch.await(); // 阻塞直到计数器归零 System.out.println("所有线程任务已完成!");
💡 经典使用场景(面试高频!)
-
并行任务汇总
比如启动10个线程爬取不同网站数据,主线程需等所有爬虫完成再整合结果。graph LR A[主线程启动] --> B[线程1-countDown] A --> C[线程2-countDown] A --> D[...countDown] B & C & D --> E[主线程await后继续] -
服务依赖检查
系统启动时检测数据库、缓存、MQ等组件是否就绪:CountDownLatch serviceLatch = new CountDownLatch(3); // 检查服务1 new Thread(() -> { checkDB(); serviceLatch.countDown(); }).start(); // 检查服务2 new Thread(() -> { checkRedis(); serviceLatch.countDown(); }).start(); // 主线程阻塞等待 serviceLatch.await(); startApplication(); // 所有服务就绪才启动应用
⚠️ 使用注意事项
- 计数器不可重置
CountDownLatch是一次性的,用完需新建。如果需要循环使用,选CyclicBarrier! - 子线程异常处理
务必在try-catch中调用countDown(),避免线程异常导致计数器永不为0,主线程死等! - 超时机制
用await(long timeout, TimeUnit unit)防止无限阻塞,增强系统健壮性:if(!latch.await(5, TimeUnit.SECONDS)) { log.error("服务启动超时!"); }
🚨 面试避坑指南
当被问到“CountDownLatch vs CyclicBarrier”时,关键抓住两点:
- 次数:前者一次性,后者可重置
- 角色:
CountDownLatch主线程是等,CyclicBarrier是所有线程互相等
举个栗子🌰:等员工到齐开会用CountDownLatch(老板等人齐);集体郊游用CyclicBarrier(互相等上车)
🎯 最后的小技巧
实际开发中,我常在分布式调度框架(如XXL-JOB)里用CountDownLatch做分片任务聚合。如果你也需要系统性提升Java并发能力,强烈推荐刷透《Java并发编程实战》+ JDK源码。
💸 福利时间:
通过面试鸭返利网购买面试鸭会员可返利25元!覆盖全网主流IT题库,性价比超高 ↓



