浅谈 Java 并发之计数器 CountDownLatch
概述
在 Java 并发编程中,CountDownLatch 是一个常用的同步工具类,可以用于控制多个线程的执行顺序,也可以用于实现线程的等待。
CountDownLatch 底层是基于 AQS(AbstractQueuedSynchronizer)实现的同步器,它的主要思想是让等待线程休眠,直到计数器计数为 0 开始执行。
使用方法
CountDownLatch 类提供了两个核心方法:countDown()
和 await()
。
public void countDown()
countDown()
方法让计数器减 1,当计数器减到 0 时,所有等待中的线程被唤醒。
```java
CountDownLatch countDownLatch = new CountDownLatch(2);
Thread thread1 = new Thread(() -> {
// do something
countDownLatch.countDown();
});
Thread thread2 = new Thread(() -> {
// do something
countDownLatch.countDown();
});
thread1.start();
thread2.start();
countDownLatch.await();
System.out.println("All threads have done their job.");
```
public void await() throws InterruptedException
await()
方法是一个阻塞方法,让当前线程等待,直到计数器归零。
```java
CountDownLatch countDownLatch = new CountDownLatch(1);
Thread thread = new Thread(() -> {
// do something
countDownLatch.countDown();
});
thread.start();
countDownLatch.await();
System.out.println("Thread has done its job.");
```
示例说明
示例一
假设有两个线程 A 和 B,线程 A 执行完后需要等待线程 B 执行完成之后才能继续执行。
public class CountDownLatchExample1 {
private static CountDownLatch countDownLatch = new CountDownLatch(1);
public static void main(String[] args) throws InterruptedException {
Thread threadA = new Thread(() -> {
// do something
System.out.println("Thread A has done its job.");
countDownLatch.countDown();
});
Thread threadB = new Thread(() -> {
// do something
System.out.println("Thread B has done its job.");
});
threadA.start();
threadB.start();
// 线程 A 等待线程 B 执行完
countDownLatch.await();
System.out.println("All threads have done their job.");
}
}
输出结果:
Thread A has done its job.
Thread B has done its job.
All threads have done their job.
示例二
假设有三个线程 A、B 和 C,线程 A 和线程 B 同时开始执行,当它们都执行完成之后,线程 C 才能执行。
public class CountDownLatchExample2 {
private static CountDownLatch countDownLatch = new CountDownLatch(2);
public static void main(String[] args) throws InterruptedException {
Thread threadA = new Thread(() -> {
// do something
System.out.println("Thread A has done its job.");
countDownLatch.countDown();
});
Thread threadB = new Thread(() -> {
// do something
System.out.println("Thread B has done its job.");
countDownLatch.countDown();
});
Thread threadC = new Thread(() -> {
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
// do something
System.out.println("Thread C has done its job.");
});
threadA.start();
threadB.start();
threadC.start();
System.out.println("All threads have started.");
}
}
输出结果:
All threads have started.
Thread A has done its job.
Thread B has done its job.
Thread C has done its job.
注意事项
- CountDownLatch 的计数器一旦减到 0,就不能再被重置,因此 CountDownLatch 是一次性的,不能重复使用,需要重新创建。
- 当线程在 await() 方法处等待时,可以中止等待,即中断当前线程,抛出 InterruptedException 异常。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅谈java并发之计数器CountDownLatch - Python技术站