Java CountDownLatch

Java CountDownLatch

CountDownLatch 是 Java 并发编程中一种简单的同步工具,核心作用是让一个线程等待一个或多个线程完成工作后再继续执行,从而避免临界资源并发访问引发的问题。

核心原理

  • 初始化时指定「倒计时次数」,代表需要等待的线程任务数量。
  • 每个被等待的线程完成工作后,调用 countDown() 方法将倒计时次数减 1。
  • 等待线程调用 await() 方法后会阻塞,直到倒计时次数变为 0 才继续执行。

完整代码实现

工人类(Worker)

封装线程要执行的具体任务,通过休眠模拟工作耗时。

package com.countdownlatch;

/**
 * 工人类:定义线程需要执行的工作逻辑
 * @author Jing61
 */
public class Worker {
    private String name;        // 工人名称
    private long workDuration;  // 工作持续时间(毫秒)

    /**
     * 构造器:初始化工人信息
     * @param name 工人名称
     * @param workDuration 工作耗时
     */
    public Worker(String name, long workDuration) {
        this.name = name;
        this.workDuration = workDuration;
    }

    /**
     * 工作执行方法:模拟具体业务逻辑
     */
    public void doWork() {
        System.out.println(name + " begins to work...");
        try {
            // 休眠对应时长,模拟实际工作执行过程
            Thread.sleep(workDuration);
        } catch (InterruptedException ex) {
            // 捕获线程中断异常,打印异常信息
            ex.printStackTrace();
        }
        System.out.println(name + " has finished the job...");
    }
}

测试线程类(WorkerTestThread)

实现 Runnable 接口,作为线程执行体,关联 Worker 和 CountDownLatch。

package com.countdownlatch;

import java.util.concurrent.CountDownLatch;

/**
 * 测试线程类:包装 Worker 任务,结合 CountDownLatch 实现同步
 * @author Jing61
 */
public class WorkerTestThread implements Runnable {
    private Worker worker;       // 关联的工人实例(具体任务)
    private CountDownLatch cdLatch; // 倒计时闩(用于同步控制)

    /**
     * 构造器:注入任务和同步工具
     * @param worker 具体工作任务
     * @param cdLatch 同步用倒计时闩
     */
    public WorkerTestThread(Worker worker, CountDownLatch cdLatch) {
        this.worker = worker;
        this.cdLatch = cdLatch;
    }

    @Override
    public void run() {
        worker.doWork();        // 执行具体工作任务
        cdLatch.countDown();    // 任务完成后,倒计时次数减 1
    }
}

主测试类(CountDownLatchTest)

初始化 CountDownLatch、Worker 实例,启动线程并实现同步等待。

package com.countdownlatch;

import java.util.concurrent.CountDownLatch;

/**
 * CountDownLatch 实战测试类:演示多线程同步等待场景
 * @author Jing61
 */
public class CountDownLatchTest {
    // 常量定义:工作时间范围(毫秒)
    private static final int MAX_WORK_DURATION = 5000;  // 最大工作时间
    private static final int MIN_WORK_DURATION = 1000;  // 最小工作时间

    /**
     * 工具方法:生成指定范围内的随机工作时间
     * @param min 最小时长
     * @param max 最大时长
     * @return 随机工作时长(毫秒)
     */
    private static long getRandomWorkDuration(long min, long max) {
        return (long) (Math.random() * (max - min) + min);
    }

    public static void main(String[] args) {
        // 1. 创建 CountDownLatch,指定需要等待 2 个线程完成
        CountDownLatch latch = new CountDownLatch(2);

        // 2. 创建 2 个工人实例,分配随机工作时长
        Worker w1 = new Worker("Peppa", getRandomWorkDuration(MIN_WORK_DURATION, MAX_WORK_DURATION));
        Worker w2 = new Worker("Emily", getRandomWorkDuration(MIN_WORK_DURATION, MAX_WORK_DURATION));

        // 3. 启动线程,执行工作任务
        new Thread(new WorkerTestThread(w1, latch)).start();
        new Thread(new WorkerTestThread(w2, latch)).start();

        try {
            // 4. 主线程阻塞等待,直到 2 个工作线程都完成(count 减为 0)
            latch.await();
            // 5. 所有线程完成后,执行后续逻辑
            System.out.println("All jobs have been finished!");
        } catch (InterruptedException e) {
            // 捕获主线程中断异常
            e.printStackTrace();
        }
    }
}

代码说明与扩展

关键方法解析

  • CountDownLatch(int count):构造器,指定需要等待的线程数量(count 为 0 时,await() 不会阻塞)。
  • countDown():倒计时次数减 1,线程安全,可被多个线程同时调用。
  • await():调用线程阻塞,直到 count 变为 0 或线程被中断。
  • 扩展方法:await(long timeout, TimeUnit unit),支持超时等待,避免无限阻塞。

典型应用场景

  • 任务拆分:主线程拆分任务给多个子线程,等待所有子线程完成后汇总结果。
  • 资源初始化:应用启动时,等待数据库、缓存等多个组件初始化完成后再提供服务。
  • 并发测试:协调多个测试线程同时开始执行,模拟高并发场景。
posted @ 2025-11-14 10:17  Jing61  阅读(12)  评论(0)    收藏  举报