coutdownlanuch 使用场景和原理

有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top

全网最细面试题手册,支持艾宾浩斯记忆法。这是一份最全面、最详细、最高质量的 java面试题,不建议你死记硬背,只要每天复习一遍,有个大概印象就行了。 https://store.amazingmemo.com/chapterDetail/1685324709017001`

CountdownLatch 使用场景和原理

使用场景

CountDownLatch 是一个同步工具类,用于协调多个线程之间的同步,或者说是等待,直到所有线程都完成某项操作。主要使用场景包括:

  1. 并发控制:当我们希望启动一些线程去执行任务,但是希望等到所有线程都准备好了再一起执行时,可以使用 CountDownLatch 来实现这一点。

  2. 开始执行前的等待:在某些应用程序启动的时候,可能需要等待必要的服务全部启动完毕,才能开始执行。

  3. 等待事件:在某些情况下,线程需要等待特定的事件发生才能继续执行。

  4. 健康检查:在微服务架构中,服务启动时可能需要进行一系列的健康检查,只有当所有的检查都通过后,服务才真正对外提供服务。

原理

CountDownLatch 的工作原理是通过一个计数器来实现的,你可以在初始化的时候指定计数器的初始值,该值表示需要等待的事件数量。CountDownLatch 提供了三个基本方法:

  • CountDownLatch(int count):构造方法,用于设置计数器的初始值。

  • void await():调用该方法的线程会被阻塞,直到计数器的值变为0。

  • void countDown():该方法会将计数器的值减1。

当计数器的值减到0时,所有调用 await() 方法并在等待的线程会被唤醒,然后继续执行。

示例代码

import java.util.concurrent.CountDownLatch;

public class Main {
    public static void main(String[] args) {
        int threads = 3;
        final CountDownLatch latch = new CountDownLatch(threads);

        for (int i = 0; i < threads; i++) {
            new Thread(new Worker(latch)).start();
        }

        try {
            // 主线程等待其他线程完成
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("所有线程已到达,主线程继续执行...");
    }

    static class Worker implements Runnable {
        private final CountDownLatch latch;

        Worker(CountDownLatch latch) {
            this.latch = latch;
        }

        @Override
        public void run() {
            try {
                // 模拟工作耗时
                Thread.sleep((long) (Math.random() * 1000));
                System.out.println(Thread.currentThread().getName() + " 完成工作");
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                // 完成工作,计数器减1
                latch.countDown();
            }
        }
    }
}

在这个例子中,我们创建了一个 CountDownLatch 实例,初始计数器值为3。然后启动了三个工作线程,每个线程完成工作后调用 countDown() 方法。主线程在调用 await() 方法后会等待,直到计数器值减到0,这时所有工作线程都已完成工作,主线程才继续执行。

最后更新于