CountDownLatch
是 Java 中的一个线程同步工具,它属于 java.util.concurrent
包。它用于在一个或多个线程等待其他线程完成一组操作的场景中。常见的使用场景包括:
- 在主线程中等待多个工作线程完成某些初始化操作
- 在多个线程之间协调某些操作的顺序
CountDownLatch
的工作原理如下:
- 初始化:在创建
CountDownLatch
对象时,指定一个初始计数值。 - 等待:一个或多个线程调用
await()
方法,这些线程会被阻塞,直到计数器减到零。 - 减少计数:当某个线程完成任务时,调用
countDown()
方法,该方法会将计数器的值减一。 - 释放:当计数器减到零时,所有调用
await()
方法的线程将被释放。
示例代码
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) {
final int numberOfThreads = 3;
CountDownLatch latch = new CountDownLatch(numberOfThreads);
// Create and start worker threads
for (int i = 0; i < numberOfThreads; i++) {
new Thread(new Worker(latch)).start();
}
try {
// Main thread waits for all worker threads to finish
latch.await();
System.out.println("All threads have finished.");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("Main thread interrupted.");
}
}
}
class Worker implements Runnable {
private final CountDownLatch latch;
public Worker(CountDownLatch latch) {
this.latch = latch;
}
@Override
public void run() {
try {
// Simulate work with sleep
System.out.println(Thread.currentThread().getName() + " is working.");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " has finished.");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println(Thread.currentThread().getName() + " was interrupted.");
} finally {
latch.countDown(); // Reduce count of the latch
}
}
}
主要方法
await()
: 使当前线程等待,直到计数器的值变为零。如果计数器已经是零,则立即返回。countDown()
: 将计数器的值减一。如果计数器的值减至零,则释放所有在await()
上等待的线程。
注意事项
CountDownLatch
不能被重置。如果你需要一个可重置的计数器,可以使用CyclicBarrier
或Semaphore
。CountDownLatch
适用于一个方向的协调,即从一个线程到其他线程,而不是双向协调。
使用 CountDownLatch
可以有效地解决线程间的同步问题,确保在执行某些操作之前,所有前置操作都已完成,确保串行化执行,而不是并发执行。