Java并发编程:CountDownLatch深入解析与实践案例

在Java并发编程中,CountDownLatch是一种常用的同步工具,它可以允许一个或多个线程等待其他线程完成某个操作。本文将深入解析CountDownLatch的工作原理,并通过实践案例展示其应用场景。
一、CountDownLatch概述
CountDownLatch类位于java.util.concurrent包中,它是一个同步辅助类,主要用于实现线程间的同步。CountDownLatch内部维护了一个计数器,初始值为给定值。当前线程可以通过调用countDown()方法将计数器减1,而其他线程则通过调用await()方法等待计数器归零。
二、CountDownLatch的工作原理
CountDownLatch的核心原理是利用AQS(AbstractQueuedSynchronizer)抽象同步器。AQS是一个提供锁机制和等待/通知功能的同步框架,CountDownLatch继承自AQS,并实现了自己的同步机制。
CountDownLatch内部维护了一个volatile类型的计数器count,用于记录剩余等待线程的数量。每个线程在执行await()方法时,会尝试获取锁。如果计数器大于0,则线程可以继续执行;如果计数器为0,则线程被唤醒,继续执行。
以下是CountDownLatch的主要方法:
1. CountDownLatch(int count):构造方法,初始化计数器count。
2. countDown():减少计数器的值。
3. await():线程等待计数器归零。
三、CountDownLatch的应用场景
1. 分阶段任务执行
在分阶段任务执行的场景中,CountDownLatch可以确保所有线程在开始下一阶段任务之前,完成当前阶段任务。以下是一个简单的示例:
```java
public class PhaseTask {
private CountDownLatch latch;
public PhaseTask(int count) {
latch = new CountDownLatch(count);
}
public void startTask() {
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
// 执行任务
System.out.println("线程" + Thread.currentThread().getName() + "开始执行");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程" + Thread.currentThread().getName() + "执行完毕");
latch.countDown();
}
}).start();
}
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("所有线程执行完毕");
}
}
```
2. 并发测试
在并发测试中,CountDownLatch可以用来统计并发执行任务的线程数量。以下是一个示例:
```java
public class ConcurrencyTest {
private CountDownLatch latch;
public ConcurrencyTest(int count) {
latch = new CountDownLatch(count);
}
public void startTest() {
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
// 执行任务
System.out.println("线程" + Thread.currentThread().getName() + "开始执行");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程" + Thread.currentThread().getName() + "执行完毕");
latch.countDown();
}
}).start();
}
try {
System.out.println("等待所有线程执行完毕...");
latch.await();
System.out.println("所有线程执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
```
3. 资源管理
在资源管理场景中,CountDownLatch可以用来确保所有线程在访问资源之前,完成对资源的准备。以下是一个示例:
```java
public class ResourceManager {
private CountDownLatch latch;
public ResourceManager(int count) {
latch = new CountDownLatch(count);
}
public void prepareResource() {
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
// 准备资源
System.out.println("线程" + Thread.currentThread().getName() + "开始准备资源");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程" + Thread.currentThread().getName() + "准备资源完毕");
latch.countDown();
}
}).start();
}
try {
System.out.println("等待所有线程准备资源完毕...");
latch.await();
System.out.println("所有线程准备资源完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
```
四、总结
CountDownLatch是Java并发编程中常用的同步工具,它可以有效地实现线程间的同步。通过本文的解析和实践案例,相信读者已经对CountDownLatch有了更深入的了解。在实际开发中,灵活运用CountDownLatch,可以提高程序的并发性能和稳定性。






