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;}@Overridepublic 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),支持超时等待,避免无限阻塞。
典型应用场景
- 任务拆分:主线程拆分任务给多个子线程,等待所有子线程完成后汇总结果。
- 资源初始化:应用启动时,等待数据库、缓存等多个组件初始化完成后再提供服务。
- 并发测试:协调多个测试线程同时开始执行,模拟高并发场景。