一文读懂CountDownLatch:Java程序员的并发神器
2023-10-19 05:37:01
什么是 CountDownLatch?
想像一下你正在主持一场竞赛,共有 10 位参赛者。你需要等待所有参赛者都完成比赛,才能宣布获胜者。而 CountDownLatch 正如其名,是一个倒计时计数器,可以让你在所有线程或任务完成之前暂停主线程。
CountDownLatch 的工作原理
创建 CountDownLatch 对象时,你需要指定等待的线程或任务数。每个线程或任务完成时,调用 countDown()
方法递减计数器。当计数器减为 0 时,等待的线程将被唤醒。
CountDownLatch 的使用
使用 CountDownLatch 非常简单,只需以下步骤:
- 创建一个 CountDownLatch 对象,指定等待的任务或线程数。
- 在每个任务或线程中,完成任务或线程后调用
countDown()
方法。 - 在主线程中,调用
await()
方法等待所有任务或线程完成。
CountDownLatch 的核心方法
CountDownLatch 有两个核心方法:
- countDown() 方法: 递减计数器。当计数器减为 0 时,等待的线程将被唤醒。
- await() 方法: 阻塞线程,直到计数器减为 0。如果计数器已减为 0,
await()
方法将立即返回。
CountDownLatch 的应用场景
CountDownLatch 可用于多种同步场景,例如:
- 等待所有线程完成任务,再执行下一步。
- 等待某个条件满足,再执行。
- 控制线程之间的协作。
CountDownLatch 源码分析
CountDownLatch 的源码位于 java.util.concurrent.CountDownLatch
类中。CountDownLatch 类包含一个计数器和一个等待队列。当计数器减为 0 时,等待队列中的所有线程都会被唤醒。
总结
CountDownLatch 是一个非常有用的并发工具,可以用来实现各种同步机制。CountDownLatch 的使用非常简单,只需要几个简单的步骤。CountDownLatch 的源码也很简单,它包含一个计数器和一个等待队列。
常见问题解答
-
什么时候使用 CountDownLatch?
当需要等待一组线程完成任务时,可以使用 CountDownLatch。
-
CountDownLatch 与 CyclicBarrier 有什么区别?
CountDownLatch 只使用一次,而 CyclicBarrier 可以重复使用。
-
CountDownLatch 与 Semaphore 有什么区别?
CountDownLatch 用于等待一组线程完成任务,而 Semaphore 用于控制同时可以访问资源的线程数。
-
CountDownLatch 的性能如何?
CountDownLatch 的性能开销很低,因为它是一个轻量级工具。
-
CountDownLatch 有哪些替代方案?
使用
join()
方法等待线程完成,或者使用Future
和ExecutorService
来管理线程。
代码示例
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CountDownLatchExample {
public static void main(String[] args) {
int threadCount = 10;
CountDownLatch latch = new CountDownLatch(threadCount);
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
// 创建并执行任务
for (int i = 0; i < threadCount; i++) {
executor.submit(() -> {
// 模拟任务
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 递减计数器
latch.countDown();
});
}
// 等待所有任务完成
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 所有任务完成,继续执行
System.out.println("所有任务已完成");
}
}