Java中的CountDownLatch及其使用
引言
在并发编程中,我们经常会遇到这样的场景:主线程需要等待所有子线程执行完成后再执行后续操作。Java提供了CountDownLatch
来解决这个问题。本文将详细介绍CountDownLatch
的用法,并给出相关的代码示例。
CountDownLatch简介
CountDownLatch
是Java并发包(java.util.concurrent)中的一个类,用于控制多线程并发执行的顺序。它通过一个计数器来实现,该计数器初始化为一个正整数,每当一个线程完成任务后,计数器的值就减1。当计数器的值为0时,表示所有线程都已经完成任务,此时主线程即可执行后续操作。
CountDownLatch
的构造函数接收一个int类型的参数,用于指定计数器的初始值。计数器的值只能被设置一次,一旦被设置为0后,就无法再重新设置。
CountDownLatch
提供了三个主要方法:
countDown()
:将计数器的值减1。await()
:使当前线程等待,直到计数器的值为0。await(long timeout, TimeUnit unit)
:使当前线程等待一段时间,直到计数器的值为0或者到达指定的超时时间。
CountDownLatch的使用示例
下面通过一个具体的示例来演示CountDownLatch
的使用。
假设有一个订单处理系统,订单处理流程包括以下几个步骤:
- 从数据库中读取订单信息。
- 调用第三方接口进行支付操作。
- 将支付结果保存到数据库中。
其中,步骤2需要花费较长的时间。
首先,我们定义一个OrderProcessor
类来处理订单。该类继承自Thread
类,表示一个订单处理线程。
public class OrderProcessor extends Thread {
private String orderId;
private CountDownLatch latch;
public OrderProcessor(String orderId, CountDownLatch latch) {
this.orderId = orderId;
this.latch = latch;
}
@Override
public void run() {
// 从数据库中读取订单信息
Order order = getOrderFromDatabase(orderId);
// 调用第三方接口进行支付操作
boolean result = pay(order);
// 将支付结果保存到数据库中
savePaymentResult(orderId, result);
// 计数器减1
latch.countDown();
}
// 省略其他方法
}
在run()
方法中,我们首先从数据库中读取订单信息,然后调用第三方接口进行支付操作,最后将支付结果保存到数据库中。在执行完这些操作后,我们调用countDown()
方法将计数器的值减1。
接下来,我们需要在主线程中等待所有订单处理线程执行完成后再进行后续操作。
public class MainThread {
public static void main(String[] args) {
// 从数据库中获取订单列表
List<String> orderIds = getOrderIdsFromDatabase();
// 创建计数器,初始值为订单数量
CountDownLatch latch = new CountDownLatch(orderIds.size());
// 创建订单处理线程并启动
for (String orderId : orderIds) {
OrderProcessor processor = new OrderProcessor(orderId, latch);
processor.start();
}
try {
// 等待所有订单处理线程执行完成
latch.await();
// 所有订单处理完成后,执行后续操作
System.out.println("所有订单处理完成");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 省略其他方法
}
在主线程中,我们首先从数据库中获取订单列表,然后创建一个CountDownLatch
对象,初始值设置为订单数量。接下来,我们创建订单处理线程并启动,每个订单处理线程都传入相同的计数器对象。最后,我们调用await()
方法使主线程等待,直到所有订单处理线程执行完成。
当所有订单处理线程执行完成后,主线程继续执行后续操作。
类图
下面是OrderProcessor
类和MainThread
类的类图:
classDiagram
class OrderProcessor {
- String orderId
- CountDownLatch latch