MST

星途 面试题库

面试题:Java并发编程中Future模式的应用及原理

解释Java并发编程中Future模式的工作原理。在实际项目场景中,假设你需要从多个远程服务获取数据,如何使用Future模式优化这个过程?请给出核心代码示例并说明关键点。
49.5万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

Future模式工作原理

  1. 基本概念:Future模式是一种异步计算的设计模式。它允许我们在调用一个可能需要较长时间执行的方法时,立即返回一个Future对象,而不是等待方法执行完成。调用者可以在后续需要结果的时候,通过Future对象获取实际的计算结果。
  2. 工作流程
    • 提交任务:调用者将任务提交给线程池或其他执行服务。
    • 返回Future:执行服务立即返回一个Future对象给调用者,该Future对象代表了任务的执行结果,但此时任务可能还未开始执行或正在执行中。
    • 异步执行:任务在另一个线程中开始执行。
    • 获取结果:调用者在需要结果的时候,通过调用Future的get()方法来获取任务的执行结果。如果任务已经完成,get()方法会立即返回结果;如果任务还未完成,get()方法会阻塞当前线程,直到任务完成并返回结果。

使用Future模式优化从多个远程服务获取数据

  1. 核心代码示例
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

class RemoteService {
    public static String getDataFromRemoteService(String serviceName) {
        // 模拟远程服务调用,这里睡眠一段时间
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "Data from " + serviceName;
    }
}

public class FutureExample {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        List<Future<String>> futures = new ArrayList<>();

        List<String> serviceNames = List.of("Service1", "Service2", "Service3");
        for (String serviceName : serviceNames) {
            Future<String> future = executorService.submit(() -> RemoteService.getDataFromRemoteService(serviceName));
            futures.add(future);
        }

        List<String> results = new ArrayList<>();
        for (Future<String> future : futures) {
            try {
                results.add(future.get());
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }

        executorService.shutdown();

        results.forEach(System.out::println);
    }
}
  1. 关键点说明
    • 线程池:使用ExecutorService创建线程池,线程池的大小根据实际情况调整,这里设置为3,表示同时可以有3个远程服务调用并发执行。
    • 任务提交:通过executorService.submit(Callable<T>)方法将每个远程服务调用任务提交给线程池,返回对应的Future<String>对象,Callable接口的实现中包含实际的远程服务调用逻辑。
    • 结果获取:遍历Future列表,调用future.get()方法获取每个远程服务调用的结果。如果某个任务还未完成,get()方法会阻塞当前线程,直到任务完成。
    • 资源关闭:在所有任务执行完毕后,调用executorService.shutdown()关闭线程池,释放资源。

通过这种方式,可以并行地发起多个远程服务调用,而不是顺序执行,从而大大提高获取数据的效率。