MST

星途 面试题库

面试题:Java中CountDownLatch在多线程协作场景的应用

请描述一个具体场景,在该场景中使用Java的CountDownLatch实现多个线程等待某个初始化操作完成后再同时执行,并给出相应的代码示例。
20.9万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

场景描述

假设我们正在开发一个游戏启动系统,在游戏正式开始前,需要加载多个游戏资源,如地图数据、角色模型、背景音乐等。只有当所有这些资源都加载完成后,游戏才能正式开始。这里我们可以使用CountDownLatch来实现让游戏启动线程等待所有资源加载线程完成初始化操作,然后再同时执行游戏启动逻辑。

代码示例

import java.util.concurrent.CountDownLatch;

class ResourceLoader implements Runnable {
    private final String resourceName;
    private final CountDownLatch latch;

    public ResourceLoader(String resourceName, CountDownLatch latch) {
        this.resourceName = resourceName;
        this.latch = latch;
    }

    @Override
    public void run() {
        try {
            System.out.println("开始加载资源: " + resourceName);
            // 模拟资源加载耗时
            Thread.sleep((long) (Math.random() * 3000));
            System.out.println("资源 " + resourceName + " 加载完成");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            latch.countDown();
        }
    }
}

public class GameLauncher {
    public static void main(String[] args) {
        int resourceCount = 3;
        CountDownLatch latch = new CountDownLatch(resourceCount);

        Thread resourceLoader1 = new Thread(new ResourceLoader("地图数据", latch));
        Thread resourceLoader2 = new Thread(new ResourceLoader("角色模型", latch));
        Thread resourceLoader3 = new Thread(new ResourceLoader("背景音乐", latch));

        resourceLoader1.start();
        resourceLoader2.start();
        resourceLoader3.start();

        try {
            System.out.println("等待所有资源加载完成...");
            latch.await();
            System.out.println("所有资源加载完成,游戏开始!");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

在上述代码中:

  1. ResourceLoader类实现了Runnable接口,每个ResourceLoader线程负责加载一种资源,加载完成后调用latch.countDown()方法,减少CountDownLatch的计数。
  2. GameLaunchermain方法中,创建了3个ResourceLoader线程来模拟加载不同的游戏资源,并创建了一个CountDownLatch对象,初始计数值为3。
  3. GameLauncher主线程调用latch.await()方法等待,直到CountDownLatch的计数值变为0,即所有资源都加载完成,然后才会继续执行游戏启动的逻辑。