全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-10 10 分钟 ✍️ juanwangdev

CountDownLatch、CyclicBarrier、Semaphore

三者都是 java.util.concurrent 包下的并发协调工具,用于控制多线程执行顺序。

CountDownLatch(倒计时锁)

作用

  • 一等多:一个线程等待其他多个线程完成
  • 计数器递减,归零时触发

使用示例

Java
// 主线程等待3个工作线程完成
CountDownLatch latch = new CountDownLatch(3);

for (int i = 0; i < 3; i++) {
    new Thread(() -> {
        // 执行任务
        latch.countDown();  // 计数减1
    }).start();
}

latch.await();  // 主线程等待,计数归零后继续
System.out.println("所有工作线程完成");

特点

  • 计数器只能递减,不可重置
  • 一次性使用,计数归零后无法复用
  • await() 可设置超时:latch.await(5, TimeUnit.SECONDS)

适用场景

  • 主线程等待多个子任务完成
  • 服务启动等待多个组件就绪

CyclicBarrier(循环屏障)

作用

  • 多等多:多个线程互相等待,都到达屏障点后一起继续
  • 可循环使用

使用示例

Java
// 3个线程互相等待,都到达后一起继续
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
    System.out.println("所有线程到达屏障,执行汇总");
});

for (int i = 0; i < 3; i++) {
    new Thread(() -> {
        // 第一阶段工作
        barrier.await();  // 等待其他线程
        // 第二阶段工作(所有线程都到达后一起执行)
    }).start();
}

特点

  • 计数器可重置,循环使用
  • 可指定屏障动作:所有线程到达后执行回调
  • await() 可设置超时

适用场景

  • 多线程分阶段并行计算
  • 多线程定时汇总

Semaphore(信号量)

作用

  • 控制同时访问资源的线程数量
  • 可用于限流

使用示例

Java
// 允许3个线程同时访问
Semaphore semaphore = new Semaphore(3);

for (int i = 0; i < 10; i++) {
    new Thread(() -> {
        try {
            semaphore.acquire();  // 获取许可(最多3个同时持有)
            // 访问受限资源
        } finally {
            semaphore.release();  // 释放许可
        }
    }).start();
}

特点

  • 可设置公平/非公平:new Semaphore(3, true) 为公平模式
  • acquire() 可设置超时:semaphore.tryAcquire(3, TimeUnit.SECONDS)
  • 可动态调整许可数量

适用场景

  • 限流:控制并发访问数量
  • 资源池:如数据库连接池控制

三者对比

特性CountDownLatchCyclicBarrierSemaphore
作用一等多多等多控制并发数
计数方向递减递增到阈值不计数
是否可重用❌ 一次性✅ 可循环✅ 可复用
等待触发计数归零达到指定数量获取许可
适用场景等待子任务完成分阶段协作并发限流

典型场景示例

CountDownLatch:等待所有任务完成

Java
CountDownLatch latch = new CountDownLatch(5);
ExecutorService executor = Executors.newFixedThreadPool(5);

for (int i = 0; i < 5; i++) {
    executor.submit(() -> {
        try {
            // 处理任务
        } finally {
            latch.countDown();
        }
    });
}

latch.await();
executor.shutdown();

CyclicBarrier:分阶段并行处理

Java
CyclicBarrier barrier = new CyclicBarrier(10);
ExecutorService executor = Executors.newFixedThreadPool(10);

for (int i = 0; i < 10; i++) {
    executor.submit(() -> {
        phase1();
        barrier.await();  // 等待所有线程完成阶段1
        phase2();
        barrier.await();  // 等待所有线程完成阶段2
    });
}

Semaphore:数据库连接限流

Java
Semaphore semaphore = new Semaphore(10);  // 最多10个并发

public Connection getConnection() throws InterruptedException {
    semaphore.acquire();
    return connectionPool.borrowConnection();
}

public void releaseConnection(Connection conn) {
    connectionPool.returnConnection(conn);
    semaphore.release();
}

要点总结

  • CountDownLatch:一等多,计数递减,一次性,适合等待子任务完成
  • CyclicBarrier:多等多,可循环,适合分阶段协作
  • Semaphore:控制并发数量,可复用,适合限流
  • CountDownLatch 计数归零后不可复用,CyclicBarrier 可循环使用
  • Semaphore 可动态调整许可,支持公平/非公平模式

📝 发现内容有误?点击此处直接编辑

← 上一篇 Java类加载机制与双亲委派模型
下一篇 → Lock 接口与 ReentrantLock
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库