MST

星途 面试题库

面试题:Java多线程编程中CountDownLatch的使用场景及原理

请描述Java多线程编程中CountDownLatch的常见使用场景,并解释其内部的工作原理,同时给出一个简单的代码示例展示如何使用它。
47.3万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

常见使用场景

  1. 线程同步:多个线程需要等待某个条件完成后再继续执行。例如,在一个应用程序启动时,可能有多个初始化线程并行执行不同的初始化任务(如加载配置文件、连接数据库等),主线程需要等待所有这些初始化任务完成后才能正式启动应用程序。
  2. 并发性能测试:模拟并发场景,让多个线程同时开始执行任务,以测试系统在高并发情况下的性能。通过CountDownLatch可以确保所有线程在同一时刻开始执行任务。

工作原理

CountDownLatch内部维护一个计数器,该计数器的初始值为需要等待的操作数。当调用 countDown() 方法时,计数器的值减1。当计数器的值变为0时,所有调用 await() 方法而进入等待状态的线程将被释放,继续执行后续的操作。

代码示例

import java.util.concurrent.CountDownLatch;

public class CountDownLatchExample {
    public static void main(String[] args) {
        // 计数器初始值为3
        CountDownLatch latch = new CountDownLatch(3);

        Thread thread1 = new Thread(() -> {
            try {
                System.out.println("Thread 1 is working");
                // 模拟任务执行
                Thread.sleep(2000);
                System.out.println("Thread 1 has finished");
                latch.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread thread2 = new Thread(() -> {
            try {
                System.out.println("Thread 2 is working");
                // 模拟任务执行
                Thread.sleep(3000);
                System.out.println("Thread 2 has finished");
                latch.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread thread3 = new Thread(() -> {
            try {
                System.out.println("Thread 3 is working");
                // 模拟任务执行
                Thread.sleep(1000);
                System.out.println("Thread 3 has finished");
                latch.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        thread1.start();
        thread2.start();
        thread3.start();

        try {
            System.out.println("Main thread is waiting for all threads to finish");
            latch.await();
            System.out.println("All threads have finished, main thread can continue");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}