作为Java开发人员,我们经常会遇到需要协调多个线程执行的情况。在这种情况下,CountDownLatch 类成为了一个强大而实用的工具。本文将深入探讨CountDownLatch 类的核心功能、类继承关系、实现原理,并通过具体的示例来说明其用法,同时提供注意事项,帮助新手Java开发人员更好地理解和使用这一类。
CountDownLatch的核心功能
CountDownLatch 是Java并发包(java.util.concurrent)中的一个类,其核心功能是允许一个或多个线程等待其他线程完成操作。其主要方法是 await() 和 countDown()。当一个线程调用 await() 方法时,它会一直等待,直到 countDown() 方法的计数器归零为止。
类继承关系
CountDownLatch 类并不涉及继承,它是直接实现的。它位于 java.util.concurrent 包中,是该包中的一个重要成员。
实现原理
CountDownLatch 的实现基于AQS(AbstractQueuedSynchronizer)类,内部维护了一个计数器(count),初始值由构造方法指定。await() 方法会使调用线程阻塞,直到计数器变为0;而 countDown() 方法会将计数器减1。当计数器归零时,所有等待的线程都会被释放。
示例说明
1. 多线程任务协同
import java.util.concurrent.CountDownLatch;
public class TaskCoordinator {
public static void main(String[] args) throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(3);
Runnable task = () -> {
System.out.println("Task is running...");
latch.countDown(); // 减少计数器
};
// 创建并启动三个线程执行任务
for (int i = 0; i < 3; i++) {
new Thread(task).start();
}
latch.await(); // 等待所有任务完成
System.out.println("All tasks are completed.");
}
}
2. 主线程等待多个子线程完成
import java.util.concurrent.CountDownLatch;
public class MainThread {
public static void main(String[] args) throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(2);
// 启动两个子线程
new Thread(() -> {
System.out.println("Task 1 is running...");
latch.countDown(); // 减少计数器
}).start();
new Thread(() -> {
System.out.println("Task 2 is running...");
latch.countDown(); // 减少计数器
}).start();
latch.await(); // 主线程等待两个子线程完成
System.out.println("All tasks are completed.");
}
}
注意事项
- 在使用
CountDownLatch时,要确保调用countDown()方法的次数等于构造方法中指定的初始值,否则会导致await()方法永远阻塞。 - 使用
CountDownLatch时需要注意避免死锁,确保countDown()方法被正确调用,以避免线程一直阻塞。