跳转到内容

CountDownLatch同步器


CountDownLatch 是 JUC(Java Util Concurrent,即 Java 并发工具包)中的一个同步辅助类。它的作用是让一个或多个线程(等待线程 A)等待其他线程(工作线程 B)完成任务后再继续执行。CountDownLatch 通过计数器实现,计数器初始值由构造方法指定,每当一个工作线程完成任务,计数器就会递减;当计数器减为零时,所有等待线程会被唤醒并继续执行。

  1. 计数器 count

    • 内部维护一个计数器,初始值由构造方法传入;

    • 表示 还有多少工作线程的任务未完成

  2. 被等待线程(工作线程 B)

    • 执行具体任务;

    • 任务完成后调用 countDown(),计数器减 1;

    • 作用:通知等待线程自己完成了任务。

  3. 阻塞线程(等待线程 A)

    • 调用 await() 方法被阻塞;

    • 当计数器减为 0 时被唤醒,继续执行后续操作;

    • 作用:等待所有工作线程完成任务。

协调线程,控制线程执行顺序。

  • 主线程等待子任务完成

主线程要汇总结果,但必须等所有子线程完成任务才能开始。

  • 线程等待某个条件完成

多个线程需要等系统初始化完成才能开始处理业务。

  • 并发测试/压测

模拟多个线程同时开始执行某段代码。

import java.util.concurrent.CountDownLatch;
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
int taskCount = 3;
CountDownLatch latch = new CountDownLatch(taskCount);
for (int i = 1; i <= taskCount; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " 执行任务...");
try { Thread.sleep(1000); } catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + " 任务完成");
latch.countDown();
}, "任务-" + i).start();
}
System.out.println("主线程等待任务完成...");
latch.await();
System.out.println("所有任务完成,主线程继续");
}
}

CountDownLatch 的内部是基于 AbstractQueuedSynchronizer(AQS)实现的,计数器的递减操作通过 AQS 来保证线程安全的同步。当调用 countDown() 时,AQS 的内部 state 会减少;而在 await() 中,会通过检查 state 是否为 0 来决定等待线程是否被唤醒继续执行。

  1. await()

    • 调用 sync.acquireSharedInterruptibly(1) 阻塞线程;

    • AQS 会检查 count 是否为 0;

    • 如果是 0 → 立即返回;

    • 如果不是 0 → 线程进入等待队列,阻塞。

  2. countDown()

    • 调用 sync.releaseShared(1)

    • 内部将计数器减 1;

    • 如果减到 0 → 唤醒所有等待线程。