Java并发编程之CountDownLatch

1. 基本原理

  • 计数器
    CountDownLatch 在创建时需要指定一个初始计数值。这个值通常代表需要等待完成的任务数或线程数。

  • 等待与递减

    • 等待:调用 await() 方法的线程会被阻塞,直到计数器变为 0。
    • 递减:每当一个任务完成后,应调用 countDown() 方法来将计数器减 1。当计数器减到 0 时,所有等待的线程将被唤醒,继续执行后续任务。

2. 主要方法

  • await()
    当前线程调用此方法后,会等待直到计数器归零。也可以调用带超时参数的版本来等待一定时间后放弃等待。

  • countDown()
    每当一个任务完成时,调用此方法,将计数器减 1。一旦计数器为 0,所有等待的线程都会被释放。


3. 使用场景

  • 任务等待
    常见于主线程等待多个子线程完成各自的任务后,再进行汇总或后续处理。例如,启动多个任务加载数据,主线程在所有任务完成后开始处理数据。

  • 并发启动
    可以用来确保多个线程在同一时刻开始工作。例如,所有线程等待一个“发令枪”信号后同时开始执行任务。

  • 一次性计数器
    一旦计数器归零,CountDownLatch 就不能再重置,因此它适合用于一次性等待场景。


4. 示例代码

下面的代码展示了如何使用 CountDownLatch 等待多个线程完成任务后,再让主线程继续执行:

import java.util.concurrent.CountDownLatch;

public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        // 创建 CountDownLatch,初始计数为 3
        CountDownLatch latch = new CountDownLatch(3);
        
        // 启动 3 个线程,每个线程执行任务后调用 countDown()
        for (int i = 0; i < 3; i++) {
            new Thread(() -> {
                try {
                    System.out.println(Thread.currentThread().getName() + " 正在执行任务...");
                    Thread.sleep(2000); // 模拟任务执行耗时
                    System.out.println(Thread.currentThread().getName() + " 任务完成。");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    latch.countDown(); // 任务完成后,计数器减 1
                }
            }, "线程" + (i + 1)).start();
        }
        
        System.out.println("主线程等待所有任务完成...");
        // 主线程等待直到计数器为 0
        latch.await();
        System.out.println("所有任务完成,主线程继续执行。");
    }
}

在这个例子中,主线程调用 latch.await() 后会阻塞,直到 3 个工作线程分别调用 countDown(),使计数器归零。计数器归零后,主线程被唤醒,继续执行后续代码。


5. 注意事项

  • 一次性使用
    CountDownLatch 的计数器只能使用一次,归零后不能重新设置。

  • 正确调用
    必须保证每个任务都能调用 countDown(),否则等待的线程可能永远无法被唤醒。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值