作为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()
方法被正确调用,以避免线程一直阻塞。