## 1. 简介
CountDownLatch是Java并发包中提供的一种同步工具类。它允许一个或多个线程等待一组操作完成。CountDownLatch通过一个计数器来实现,当计数器到达0时,处于等待状态的线程就会被唤醒。
## 2. 底层实现
CountDownLatch使用了cas技术,底层是通过AQS(AbstractQueuedSynchronizer)实现的。其核心思想是等待一个或多个线程完成某一操作。在CountDownLatch内部,存在一个计数器,初始值由使用者设定,内部实现了acquire和release操作。这里就不过多讲述具体的AQS实现,感兴趣的读者可以参考Java并发编程实战。
## 3. 与CyclicBarrier的区别
CountDownLatch和CyclicBarrier都是Java中的同步工具类,但是它们之间存在一些区别:
1. CountDownLatch是一次性的,计数器的值减为0后,就无法再次使用。而CyclicBarrier是可重用的,计数器的值减为0后,可以重置并再次使用。
2. CountDownLatch的计数器是顺序倒减的,而CyclicBarrier的计数器是可循环的。
3. CountDownLatch是一次等待,线程等待多少次唤醒多少次,而CyclicBarrier是多次等待,线程等待一次,唤醒多次。
## 4. 应用场景
CountDownLatch在多线程场景下用的非常多,主要是用于等待一个或多个操作完成后再进行后续操作,比如:
1. 线程池主线程等待所有子线程执行完毕后再进行其他操作。
2. 主线程等待各个库存线程将各个库存的数据处理完成后再进行后续的业务操作。
3. 数据库连接池管理器,等待多个连接释放后再进行后续的操作。
## 5. 示例代码
下面是一个简单的CountDownLatch的例子,使用了2个线程协同工作,主线程等待两个线程都执行完毕后再输出"All threads have finished."
```java
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(2);
new Thread(() -> {
System.out.println("Thread 1 starts working!");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 1 finished working!");
countDownLatch.countDown();
}).start();
new Thread(() -> {
System.out.println("Thread 2 starts working!");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 2 finished working!");
countDownLatch.countDown();
}).start();
countDownLatch.await();
System.out.println("All threads have finished.");
}
}
```
输出结果:
```
Thread 1 starts working!
Thread 2 starts working!
Thread 1 finished working!
Thread 2 finished working!
All threads have finished.
```
以上就是CountDownLatch的使用介绍、实现原理和应用场景,希望对您有所帮助。