返回

揭秘CountDownLatch计数器:巧妙协同多线程任务

后端

进入多线程编程的世界,CountDownLatch是一个必不可少的工具。它就像一个指挥家,能够协调多个线程之间的任务执行,确保它们按照既定顺序完成。

理解CountDownLatch计数器

CountDownLatch本质上是一个计数器,用于跟踪正在运行的线程数量。在初始化CountDownLatch时,我们需要指定一个计数器值,表示需要等待的线程数量。随着线程完成各自的任务,它们会调用CountDownLatch的countDown()方法来递减计数器。当计数器达到0时,所有正在等待的线程都会被唤醒,继续执行。

CountDownLatch的妙用

CountDownLatch的典型应用场景包括:

  • 等待所有线程完成任务再执行后续操作。例如,在多线程下载任务中,我们需要等待所有线程都下载完成后,再将结果汇总。
  • 等待某个事件发生。例如,在一个分布式系统中,我们需要等待所有节点都启动完成后,再开始执行其他操作。
  • 控制线程的并发执行数量。例如,我们可以在线程池中使用CountDownLatch来限制同时运行的线程数量,防止系统资源被过度占用。

CountDownLatch实战

为了更好地理解CountDownLatch的使用,让我们来看一个实际的例子。假设我们有一个多线程文件下载任务,需要同时下载6个文件。使用CountDownLatch,我们可以确保在所有文件下载完成后再进行后续处理。

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CountDownLatchExample {

    public static void main(String[] args) {
        // 初始化CountDownLatch,计数器值为6,表示需要等待6个线程完成任务
        CountDownLatch latch = new CountDownLatch(6);

        // 创建线程池,用于执行下载任务
        ExecutorService executorService = Executors.newFixedThreadPool(6);

        // 创建6个任务,每个任务对应一个文件下载
        for (int i = 1; i <= 6; i++) {
            executorService.submit(new DownloadTask(latch, i));
        }

        // 等待所有线程完成任务
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 所有文件下载完成后,进行后续处理
        System.out.println("所有文件下载完成,开始进行后续处理");

        // 关闭线程池
        executorService.shutdown();
    }

    // 文件下载任务
    private static class DownloadTask implements Runnable {

        private CountDownLatch latch;
        private int fileIndex;

        public DownloadTask(CountDownLatch latch, int fileIndex) {
            this.latch = latch;
            this.fileIndex = fileIndex;
        }

        @Override
        public void run() {
            try {
                // 模拟文件下载
                Thread.sleep(1000);

                // 下载完成后,调用countDown()方法递减计数器
                latch.countDown();

                System.out.println("文件" + fileIndex + "下载完成");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

在上面的示例中,我们首先创建了一个CountDownLatch对象,并将其初始化为6,表示需要等待6个线程完成任务。然后,我们创建了一个线程池来执行下载任务,并为每个文件下载任务创建了一个Runnable对象。在每个Runnable对象中,我们调用CountDownLatch的countDown()方法来递减计数器。当所有线程都完成任务后,CountDownLatch的计数器将达到0,所有正在等待的线程都会被唤醒,继续执行后续处理。

结语

CountDownLatch是一个功能强大的并发编程工具,能够帮助我们协调多个线程之间的任务执行,并确保线程之间的协同工作。通过本篇文章,您已经掌握了CountDownLatch的工作原理和使用方法。赶快在您的项目中使用它,体验并发编程的魅力吧!