CountDownLatch使用场景和原理

说明:CountDownLatch 是 JUC(java.util.concurrent)包里 “一次性门闩” 同步器,一个/多个线程 在门闩上 await() 等待;另一个/另一些线程 执行完业务后 countDown() 把计数减到 0,门闩瞬间打开,所有等待线程同时通过,且 不能重复使用

使用场景:等所有人干完活再一起继续”

  • 主线程等待所有子任务完成
    -批量导入、并行计算、多线程文件解析。

  • 多线程压测/预热
    -让数千线程 同时 开始发请求(先 await,再一起 countDown)。

  • 服务启动依赖
    -微服务启动前必须 等待 DB、Redis、MQ 健康检查 全部 OK。

原理:底层 AQS 共享模式:(此处还有待理解)
await() → 如果 state > 0 则排队并 park;
countDown() → CAS 把 state–;当 state == 0 时 unpark 所有等待线程;
状态归零后 不再接受任何 countDown,门闩永远打开 → 一次性

API说明

方法 说明
new CountDownLatch(int count) 构造时指定“倒计数”初始值
void await() / await(long timeout, TimeUnit unit) 等待计数变 0/等待timeout时间
void countDown() 业务线程执行完调用,计数减 1

永久阻塞的几种方式

  • new CountDownLatch(1).await(); //计数器的值是1,没有调用countDown方法, 1 永远减不到 0 ,实现永久阻塞;
  • new CountDownLatch(0).await() ; // 实现原理同上
  • new CountDownLatch(1).await(10, TimeUnit.MINUTES); // 10 分钟后自动放行,时间可自定义

与 CyclicBarrier 区别

维度 CountDownLatch CyclicBarrier
方向 倒计时到 0 计数加到指定值
重用性 一次性 可循环使用
等待角色 一个/多个线程 等别人 所有线程 互相等
典型场景 主线程等子任务 多线程 同时 开始/分段计算

示例

public class Demo {
    public static void main(String[] args) throws InterruptedException {
        final int N = 5;
        CountDownLatch latch = new CountDownLatch(N);
        ExecutorService pool = Executors.newFixedThreadPool(N);

        for (int i = 0; i < N; i++) { // 循环N次,每次在线程池中提交一个任务
            final int idx = i;
            pool.submit(() -> {
                try {
                    // 模拟业务
                    System.out.println("task-" + idx + " 开始");
                    Thread.sleep(1000);
                    System.out.println("task-" + idx + " 结束");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    latch.countDown();   // 必须放在 finally;每个线程执行完一次,计数器就减1
                }
            });
        }
        latch.await();     // 主线程等待,等到计数器的值=0后,打印下面的日志
        System.out.println("countDownLatch=0,所有线程均已完成,主线程池继续跑");
        pool.shutdown();
    }
}

执行结果:
在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐