CountDownLatch、CyclicBarrier、Semaphore 有何区别?

结论先行:三者都是 JUC 同步工具,但语义完全不同:CountDownLatch 是倒数门闩,等 N 个线程各自报数(countDown)完成后放行等待者;CyclicBarrier 是循环栅栏,N 个线程互相等待到齐后再同时出发且可重置复用;Semaphore 是信号量,用许可数控制同时访问资源的线程上限,本质是限流。

三者对比

维度CountDownLatchCyclicBarrierSemaphore
核心语义计数归零即放行凑齐人数再开跑许可证控制并发数
等待关系主线程等一组任务完成线程们互相等齐每个线程申请/释放许可
可否复用否(一次性)是(reset 后循环使用)是(一直可用)
典型场景服务启动等所有模块就绪分批并行计算后统一汇总数据库连接池、接口限流
import java.util.concurrent.*;

public class SyncToolsDemo {
    public static void main(String[] args) throws Exception {
        // 1) CountDownLatch:3 个任务都 countDown 后主线程才继续
        CountDownLatch latch = new CountDownLatch(3);
        for (int i = 0; i < 3; i++) {
            new Thread(() -> {
                try { Thread.sleep(50); }
                catch (InterruptedException e) { Thread.currentThread().interrupt(); }
                finally { latch.countDown(); }
            }).start();
        }
        latch.await();

        // 2) CyclicBarrier:3 个线程到齐后一起“开跑”
        CyclicBarrier barrier = new CyclicBarrier(3,
                () -> System.out.println("全员到齐,开跑"));
        for (int i = 0; i < 3; i++) {
            new Thread(() -> {
                try { barrier.await(); } catch (Exception e) { }
            }).start();
        }

        // 3) Semaphore:最多发放 2 个许可
        Semaphore sem = new Semaphore(2);
        sem.acquire();
        try { /* 访问受限资源 */ } finally { sem.release(); }
    }
}

常见追问 / 记忆点

  • 记忆点:Latch 在“倒计时”、Barrier 在“凑人头”、Semaphore 在“卡并发数”。
  • 追问:CountDownLatch 计数不能回拨;CyclicBarrier 有人中断/超时后会破坏栅栏,可用 reset 重建。
  • 追问:Semaphore 同样有公平/非公平模式,acquire 可响应中断,release 会唤醒等待线程。
笔记加载中…