返回

掌握CountDownLatch,解锁Java并发编程新境界

后端

死磕Java并发:J.U.C之并发工具类:CountDownLatch

引言

在当今多线程并发编程时代,掌握高效的并发工具是至关重要的。在Java并发工具类库(J.U.C)中,CountDownLatch是一个不可忽视的利器。它可以帮助我们协调多个线程之间的执行,实现优雅的同步。

何为CountDownLatch?

CountDownLatch是一个同步辅助类,其本质是一个计数器。它允许多个线程等待,直到该计数器达到零,然后才继续执行。

工作原理

  • 创建CountDownLatch对象: 使用CountDownLatch(int count)创建CountDownLatch对象,其中count指定初始计数器值。
  • 递减计数器: 调用countDown()方法递减计数器。当计数器达到零时,所有等待的线程将被唤醒。
  • 等待计数器达到零: 调用await()方法使当前线程等待,直到计数器达到零。

实际应用场景

CountDownLatch可用于各种场景,例如:

  • 初始化完成等待: 多个线程同时执行初始化任务,使用CountDownLatch等待所有线程完成初始化,再继续主线程执行。
  • 任务完成通知: 多个线程并行执行任务,使用CountDownLatch通知主线程所有任务已完成。
  • 资源释放协调: 多个线程共享资源,使用CountDownLatch协调资源释放,确保所有线程都已释放资源后再关闭资源。

与CyclicBarrier的比较

CountDownLatch与CyclicBarrier同为J.U.C中的并发工具类,但两者存在差异:

  • 计数方式: CountDownLatch为递减计数,而CyclicBarrier为循环计数。
  • 等待方式: CountDownLatch只等待计数器达到零一次,而CyclicBarrier可以反复等待计数器达到零。
  • 唤醒方式: CountDownLatch唤醒所有等待线程,而CyclicBarrier只唤醒一个等待线程。

示例代码

以下代码示例演示了CountDownLatch的用法:

CountDownLatch latch = new CountDownLatch(3); // 初始化计数器为3

// 3个线程同时执行任务
new Thread(() -> {
    System.out.println("任务1完成");
    latch.countDown(); // 递减计数器
}).start();

new Thread(() -> {
    System.out.println("任务2完成");
    latch.countDown(); // 递减计数器
}).start();

new Thread(() -> {
    System.out.println("任务3完成");
    latch.countDown(); // 递减计数器
}).start();

latch.await(); // 等待计数器达到零

System.out.println("所有任务已完成");

结语

CountDownLatch是一个强大的并发工具,通过协调线程执行,它可以简化并发编程,避免数据竞争和死锁。掌握CountDownLatch将帮助我们编写更可靠、高效的并发代码。