题目:CountDownLatch、CyclicBarrier、Semaphore 区别?
难度:low
标签:java/juc, general/knowledge
评分:⭐⭐⭐☆☆(3/5)
三者是AQS中共享模式下的三个不同实现; countDownlatch是用于单个主线程下执行计数递减使用,每个对象只能用一次,所以要设置在主方法内使用,用过归零后就需要重新创建了,比如对资源的调用控制; cyclicbarrier是用于进行线程启动控制,用于等待多个线程到达后再执行下一步操作,可以用来进行结果组合,多线程调用不同下游,然后等待所有下游结果返回后,进行对结果统一组合; semaphore是信号量,控制一次可以通过的线程数,超过的会被阻塞,可以用来做限流,一次只允许一定个数的线程通过执行
优点:三者用途都讲对了——CDL 计数归零、CB 线程到齐、Semaphore 控制通过数量;CDL/Semaphore 属于 AQS 共享模式也对。
不足:"三者都是 AQS 共享模式"错——CyclicBarrier 是 ReentrantLock + Condition 实现的,不走 AQS。也没点出"一次性 vs 可复用"这个核心对比。
补充:CDL 一次性、CB 可循环复用(有 reset/barrierAction);CDL 等的是"事件",CB 等的是"彼此",Semaphore 控制的是"并发许可数"。
核心考点定位:三者的语义差异 + 底层实现方式。
知识点拆解:
await() 阻塞、countDown() 减到 0 唤醒全部等待线程。reset() 复用。acquire/release 控制同时通过的线程数。AQS 共享模式,state = 剩余许可。考察方向:
tryAcquireShared + doReleaseShared)延伸递进面试题:
setHeadAndPropagate 向后传播,连续唤醒共享节点【一句话结论】
面试官您好,三者都是并发协调工具,但语义和实现都不同。
【三点展开】
第一,CountDownLatch 是一次性的"等待事件",主线程 await 等计数归零,底层是 AQS 共享模式;
第二,CyclicBarrier 是可循环的"互相等待到齐",底层是 ReentrantLock + Condition——注意它不走 AQS;
第三,Semaphore 是许可信号量,控制同时通过的线程数,底层是 AQS 共享模式,常用来限流。
【一句边界】
当然,CyclicBarrier 的 reset() 会打断已等待的线程抛 BrokenBarrierException,生产环境要慎用 reset。