当前位置: 面试刷题>> 什么是 Java 的 CountDownLatch?
在Java并发编程领域,`CountDownLatch` 是一个非常有用的同步工具类,它位于 `java.util.concurrent` 包下。作为高级程序员,理解并熟练使用 `CountDownLatch` 对于编写高效、可维护的并发程序至关重要。`CountDownLatch` 允许一个或多个线程等待其他线程完成一系列操作后再继续执行。简而言之,它是一个倒计时锁存器,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
### 基本原理
`CountDownLatch` 初始化时需要一个计数器(count),该计数器表示需要等待的事件数量。每次调用 `countDown()` 方法时,计数器会减一。当计数器到达零时,所有等待(通过 `await()` 方法)的线程都会被释放,继续执行。
### 应用场景
`CountDownLatch` 非常适用于以下场景:
1. **并行计算**:当需要将一个大任务分割成多个小任务并行处理,并等待所有小任务完成后再继续执行后续操作时。
2. **资源初始化**:在多个线程需要访问某些资源之前,这些资源需要被初始化完成。
3. **性能测试**:在测试多个并发执行的操作时,等待所有操作都启动后再进行统计或验证。
### 示例代码
假设我们有一个场景,需要同时启动多个线程去加载资源,待所有资源加载完毕后,再进行下一步处理。这里我们使用 `CountDownLatch` 来实现:
```java
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
// 假设有5个资源需要加载
int numberOfResources = 5;
// 初始化CountDownLatch,计数器为5
CountDownLatch latch = new CountDownLatch(numberOfResources);
// 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(numberOfResources);
// 提交5个任务去加载资源
for (int i = 0; i < numberOfResources; i++) {
final int resourceId = i;
executor.submit(() -> {
System.out.println(Thread.currentThread().getName() + " 正在加载资源 " + resourceId);
// 模拟资源加载耗时
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
// 资源加载完成,计数器减一
latch.countDown();
});
}
// 等待所有资源加载完成
latch.await();
System.out.println("所有资源加载完成,继续后续操作...");
// 关闭线程池
executor.shutdown();
}
}
```
在这个示例中,我们创建了一个 `CountDownLatch` 实例,其计数器初始化为5,表示有5个资源需要加载。我们提交了5个任务到线程池中,每个任务加载一个资源,并在加载完成后调用 `countDown()` 方法。主线程通过调用 `await()` 方法等待,直到所有资源都被加载完成(即计数器减至0)。此时,主线程继续执行后续操作。
### 注意事项
- **避免死锁**:确保在调用 `await()` 方法的线程中,不会持有其他锁,因为 `await()` 会导致线程阻塞,可能导致死锁。
- **异常处理**:`await()` 方法会抛出 `InterruptedException`,需要妥善处理。通常的做法是重新设置中断状态,并可能根据需求中断当前操作或退出循环。
- **性能考虑**:在大量线程并发使用时,`CountDownLatch` 的性能可能受到影响。考虑使用其他并发工具,如 `CyclicBarrier` 或 `Semaphore`,根据具体场景选择最合适的工具。
通过理解并熟练使用 `CountDownLatch`,你可以编写出更加高效、灵活的并发程序,从而在码小课等平台上分享你的编程经验和知识。