1. CountDownLatch是什么
CountDownLatch 是 Java.util.concurrent 包中的一个同步工具类,用于控制线程的执行顺序。它的主要作用是让一个或多个线程等待其他线程完成操作后再继续执行。
2. CountDownLatch 类常用方法
- CountDownLatch(int count) 是 CountDownLatch 类的构造函数,用于创建一个 CountDownLatch 对象并指定初始计数值。参数 count 表示初始的计数值,即等待的线程数量。当计数值变为0时,所有等待的线程将被释放。
- getCount(): 获取当前 CountDownLatch 的计数值。
- countDown(): 将 CountDownLatch 的计数减1。每次调用该方法都会使计数减少。当计数减至0时,所有等待中的线程将被释放。
- await(): 使当前线程等待,直到 CountDownLatch 的计数减至0。当计数为0时,该方法返回。如果计数不为0,当前线程将被阻塞,直到计数为0或线程被中断。
- await(long timeout, TimeUnit unit): 使当前线程等待指定的时间,直到 CountDownLatch 的计数减至0。如果在指定的时间内计数变为0,则该方法返回 true;如果在指定的时间内计数没有变为0,则该方法返回 false。
3. CountDownLatch 的用法详解
a. 初始化 CountDownLatch
首先,需要创建一个 CountDownLatch 对象,并指定需要等待的线程数量。例如,如果有5个线程需要等待,可以这样初始化 CountDownLatch。
CountDownLatch latch = new CountDownLatch(5);
b. 等待其他线程
在需要等待的线程中调用 latch.await() 方法。这会使当前线程等待,直到 CountDownLatch 的计数减到0为止。也就是说,如果初始化时指定的等待数量是5,那么只有当其他5个线程都调用了 countDown() 方法后,latch.await() 才会返回。
try {
latch.await();
// 等待其他线程完成后继续执行的代码
} catch (InterruptedException e) {
// 处理中断异常
}
c. 完成操作
在需要等待的线程完成操作后,调用 latch.countDown() 方法来减少 CountDownLatch 的计数。每次调用 countDown() 方法都会使计数减1。
// 在需要等待的线程中执行完成操作后调用 countDown()
latch.countDown();
注意:
countDown() 方法可以在任意线程中调用,不一定需要在等待线程中调用。
使用 CountDownLatch 的典型场景是主线程等待多个子线程都完成某个操作后再继续执行。通过合理地使用 CountDownLatch,可以实现线程之间的协作和同步。
CountDownLatch 的计数是递减的,一旦计数变为0,就不能再重新设置。如果需要重新使用 CountDownLatch,需要创建一个新的实例。
4. 完整代码示例
开启10个子线程,主线程等待子线程全部完成后继续操作
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(10);
for (int i = 0; i < 10; i++) {
new Thread(() -> {
System.out.println("当前线程:" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
latch.countDown();
}
}).start();
}
System.out.println("主线程等待子线程运行结束");
// 主线程等待子线程运行结束
latch.await();
System.out.println("子线程运行结束");
System.out.println("主线程继续进行");
}
控制台输出: