返回
CountDownLatch Java并发包源码深入解析
后端
2024-01-03 07:08:35
CountDownLatch:多线程同步与通信的利器
简介
在多线程编程中,经常遇到线程同步和通信的问题。CountDownLatch 是一个用于解决这些问题的强大工具。它本质上是一个计数器,可以阻塞线程,直到计数器达到某个值。
CountDownLatch的用法
CountDownLatch的用法非常简单:
- 构造一个CountDownLatch实例,指定初始计数。
- 创建需要等待的线程。
- 在需要等待的代码段前调用CountDownLatch的
await()
** ** 方法。** - 在适当的时候调用CountDownLatch的
countDown()
** ** 方法,减小计数器。** - 计数器达到0时,所有等待线程将被唤醒。
CountDownLatch源码分析
CountDownLatch的源码并不复杂,但包含一些关键细节:
public class CountDownLatch {
private final int count;
private final AtomicLong state;
public CountDownLatch(int count) {
this.count = count;
this.state = new AtomicLong(count);
}
public void await() throws InterruptedException {
// 循环等待计数器为0
while (true) {
long current = state.get();
if (current == 0) {
return;
}
state.compareAndSet(current, current - 1);
if (state.get() == 0) {
return;
}
Thread.yield();
}
}
public void countDown() {
state.decrementAndGet();
}
}
常见的应用场景
CountDownLatch可以用于解决多种多线程问题,包括:
- 线程同步: 确保所有线程在执行关键操作之前完成特定任务。
- 线程通信: 允许线程之间安全地交换数据。
- 线程协作: 协调多个线程同时执行特定操作。
示例代码
以下代码演示了如何使用CountDownLatch来实现线程同步:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CountDownLatchDemo {
private static final int THREAD_COUNT = 5;
public static void main(String[] args) throws InterruptedException {
// 创建一个CountDownLatch,初始计数为5
CountDownLatch latch = new CountDownLatch(THREAD_COUNT);
// 创建一个线程池
ExecutorService executorService = Executors.newFixedThreadPool(THREAD_COUNT);
// 创建5个线程并提交给线程池
for (int i = 0; i < THREAD_COUNT; i++) {
executorService.submit(() -> {
try {
// 模拟每个线程执行一段任务
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 任务完成后,调用countDown()方法减小计数器
latch.countDown();
}
});
}
// 主线程等待所有子线程完成
latch.await();
// 所有子线程完成任务后,主线程继续执行
System.out.println("所有线程已完成任务!");
}
}
总结
CountDownLatch是一个简洁且强大的工具,可用于解决多线程同步和通信问题。它允许线程等待直到特定条件满足,并可用于协调和控制线程之间的交互。通过理解CountDownLatch的用法和实现,开发者可以编写出更加健壮和高效的多线程程序。
常见问题解答
- CountDownLatch与Semaphore有什么区别?
- CountDownLatch是一次性的,计数器达到0后就不能再被增加,而Semaphore是一个可重用的计数器。
- CountDownLatch与CyclicBarrier有什么区别?
- CountDownLatch用于线程同步,而CyclicBarrier用于线程协调,它允许线程在等待所有线程到达特定点后继续执行。
- CountDownLatch是否支持超时?
- CountDownLatch的
await()
方法支持超时,但countDown()
方法不支持。
- CountDownLatch的
- CountDownLatch是否线程安全?
- CountDownLatch是线程安全的。
- CountDownLatch可以用于哪些应用场景?
- CountDownLatch可用于实现线程同步、线程通信和线程协作。