Java如何返回异步方法的返回值

引言

在Java开发中,有时候我们会遇到需要进行异步操作的场景,例如发送HTTP请求、执行数据库查询等。在进行异步操作时,一个常见的需求是需要获取异步操作的返回值。本文将介绍Java中如何返回异步方法的返回值,并提供一个实际问题的解决方案。

问题背景

假设我们正在开发一个电商网站,我们的系统需要从多个供应商获取产品信息。为了提高系统的响应速度,我们希望能够并发地从多个供应商接口获取产品信息。每个供应商接口都是异步的,我们需要等待所有供应商接口的返回结果,并将结果合并后返回给前端。

解决方案

Java提供了多种方式来返回异步方法的返回值,本文将介绍两种常见的方式:使用Future和CompletableFuture。

方式一:使用Future

Future是Java提供的一个用于表示异步计算结果的接口,我们可以通过调用Future的get()方法来等待异步操作的完成,并获取其返回值。

首先,我们需要定义一个供应商接口的类 Supplier,该类包含一个异步方法 getProductInfo(),用于获取产品信息。

public interface Supplier {
    Future<ProductInfo> getProductInfo();
}

然后,我们可以创建一个线程池来执行供应商接口的异步方法。

ExecutorService executor = Executors.newFixedThreadPool(5);

接下来,我们可以并发地执行多个供应商接口的异步方法,并等待所有异步操作的完成。

List<Future<ProductInfo>> futures = new ArrayList<>();

for (Supplier supplier : suppliers) {
    futures.add(supplier.getProductInfo());
}

List<ProductInfo> results = new ArrayList<>();

for (Future<ProductInfo> future : futures) {
    try {
        ProductInfo result = future.get();
        results.add(result);
    } catch (InterruptedException | ExecutionException e) {
        // 处理异常
    }
}

最后,我们可以将所有供应商接口的返回结果合并,并返回给前端。

return mergeResults(results);

方式二:使用CompletableFuture

CompletableFuture是Java 8引入的一个用于处理异步操作的类,相比于Future,CompletableFuture提供了更加灵活和强大的功能。

首先,我们需要定义一个供应商接口的类 Supplier,该类包含一个异步方法 getProductInfo(),用于获取产品信息。

public interface Supplier {
    CompletableFuture<ProductInfo> getProductInfo();
}

然后,我们可以创建一个CompletableFuture对象,使用它的supplyAsync()方法来执行供应商接口的异步方法。

CompletableFuture<ProductInfo> future = CompletableFuture.supplyAsync(supplier::getProductInfo);

接下来,我们可以使用CompletableFuture的静态方法allOf()来等待所有异步操作的完成。

CompletableFuture<Void> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));

然后,我们可以使用CompletableFuture的join()方法来获取异步操作的结果。

List<ProductInfo> results = allFutures
    .thenApply(v -> futures.stream()
        .map(CompletableFuture::join)
        .collect(Collectors.toList()))
    .join();

最后,我们可以将所有供应商接口的返回结果合并,并返回给前端。

return mergeResults(results);

示例

下面是一个示例代码,演示了如何使用CompletableFuture来返回异步方法的返回值。

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

public class Supplier {
    public CompletableFuture<String> getProductInfo() {
        return CompletableFuture.supplyAsync(() -> {
            // 模拟异步操作
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Product Info";
        });
    }
}

public class Main {
    public static void main(String[] args) {
        Supplier supplier = new Supplier();

        CompletableFuture<String> future = supplier.getProductInfo();

        future.thenAccept(result -> {
            System.out.println("Result: " + result);
        });

        // 等待异步操作的完成
        try {
            future.get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

类图

下面是类图,表示了Supplier类的关系。

classDiagram
    class Supplier {
        + CompletableFuture<ProductInfo