Skip to Content
面试题库Juc[面试题] CountDownLatch、CyclicBarrier、Semaphore 有什么区别?分别适合什么场景?

[面试题] CountDownLatch、CyclicBarrier、Semaphore 有什么区别?分别适合什么场景?

📖 版块 A:知识讲解版 (温故知新)

  • CountDownLatch

    1. 本质是一个倒计时门闩
    2. 一个或多个线程等待,直到其他线程把计数减到 0。
    3. 一次性使用,计数归零后不能重置。
  • CyclicBarrier

    1. 本质是一个可循环使用的屏障
    2. 一组线程彼此等待,直到所有参与者都到达屏障点后再一起继续。
    3. 支持重复使用,支持 barrier action。
  • Semaphore

    1. 本质是一个许可证控制器
    2. 通过 acquire / release 控制同时访问某资源的线程数量。
    3. 适合做限流、资源池并发控制。
  • 底层共性

    • 都属于 JUC 同步器。
    • CountDownLatchSemaphore 底层都基于 AQS。
    • CyclicBarrier 内部则更多依赖 ReentrantLock + Condition 协调等待线程。
  • 典型场景

    1. CountDownLatch:主线程等待多个子任务完成。
    2. CyclicBarrier:多线程分阶段并行计算。
    3. Semaphore:控制数据库连接数、接口并发数、线程池外层限流。

🎤 版块 B:面试实战版 (高手逐字稿)

Q:CountDownLatch、CyclicBarrier、Semaphore 有什么区别?分别适合什么场景?

💬 高手逐字稿

这三个类都属于 JUC 里的同步工具,但它们解决的不是同一种问题。

CountDownLatch 解决的是“等完成”的问题。它内部有一个倒计时,主线程或者某个协调线程会在那儿等着,其他工作线程每完成一部分任务就 countDown() 一次,直到计数减到 0,等待线程才会继续执行。所以它特别像项目管理里的“收尾检查”,比如主线程要等 10 个分片任务都跑完,再做结果汇总。它的一个关键特征是一次性,计数器归零之后不能复原。

CyclicBarrier 解决的是“等人齐”的问题。它要求一组线程都跑到某个屏障点,谁先到谁先等,直到最后一个线程也到了,大家再一起往后走。这个模型很适合分阶段并行计算,比如多线程分别算一部分数据,每轮算完后统一汇总,再进入下一轮。它叫 Cyclic,就是因为它可以重复使用,不像 Latch 用一次就结束了。

Semaphore 解决的是“等名额”的问题。它内部维护一组许可证,线程拿到许可证才能继续执行,执行完再归还。它本质上不是让线程互相等待,而是在控制某个资源同时最多允许多少访问者。比如数据库连接池只有 20 个名额,或者某个下游接口我们只想放 50 个并发请求,Semaphore 就非常合适。

如果我用一句话区分它们:

  • CountDownLatch 是“等任务做完”;
  • CyclicBarrier 是“等队友到齐”;
  • Semaphore 是“等资源名额”。

再补一个细节:很多人会把 CountDownLatchCyclicBarrier 混掉。最大的区别其实是等待关系不同。CountDownLatch 通常是少数线程等多数线程,像主线程等子线程;CyclicBarrier 则是参与者彼此互等,大家地位是对等的。

最后更新于:
⏱️

登录后开始阅读

当前 MVP 版本只开放邮箱密码登录注册。完成登录后即可进入面试题内容。

还没有账号?先去注册