2025.6.5

CompletableFuture.supplyAsync() 是 Java 8 引入的异步任务执行方式,适用于 需要返回结果 的异步计算场景。它会在后台线程中执行任务,并返回一个 CompletableFuture<T> 对象,最终可以通过 get() 或回调方法获取结果。


简单示例

示例 1:基本用法(计算并返回字符串)

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class SupplyAsyncExample {
    public static void main(String[] args) {
        // 异步执行任务(返回结果)
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000); // 模拟耗时操作
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Hello, CompletableFuture!";
        });

        // 阻塞获取结果(实际开发中尽量避免直接调用 get())
        try {
            String result = future.get();
            System.out.println(result); // 输出: Hello, CompletableFuture!
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

示例 2:链式处理(thenApply + thenAccept

CompletableFuture.supplyAsync(() -> {
    return 42; // 返回初始值
}).thenApply(number -> {
    return number * 2; // 对结果进行转换
}).thenAccept(result -> {
    System.out.println("最终结果: " + result); // 输出: 最终结果: 84
});

关键点

  1. supplyAsync vs runAsync

    • supplyAsync:接受 Supplier<T>,返回 CompletableFuture<T>(有返回值)。
    • runAsync:接受 Runnable,返回 CompletableFuture<Void>(无返回值)。
  2. 默认线程池
    如果不指定 Executor,默认使用 ForkJoinPool.commonPool()。可以通过第二个参数指定自定义线程池:

    ExecutorService customExecutor = Executors.newFixedThreadPool(5);
    CompletableFuture.supplyAsync(() -> "Custom Thread", customExecutor);
    
  3. 异常处理
    使用 exceptionallyhandle 处理异常:

    CompletableFuture.supplyAsync(() -> {
        if (Math.random() > 0.5) {
            throw new RuntimeException("模拟异常");
        }
        return "Success";
    }).exceptionally(ex -> {
        System.out.println("出错: " + ex.getMessage());
        return "Fallback Value";
    }).thenAccept(System.out::println);
    

实际应用场景

1. 异步查询数据库

CompletableFuture.supplyAsync(() -> {
    return database.query("SELECT * FROM users WHERE id = 1"); // 模拟数据库查询
}).thenAccept(user -> {
    System.out.println("查询结果: " + user);
});

2. 并行调用多个服务

CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> callServiceA());
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> callServiceB());

// 合并两个异步任务的结果
future1.thenCombine(future2, (resultA, resultB) -> {
    return resultA + " + " + resultB;
}).thenAccept(System.out::println);

总结

  • 何时用 supplyAsync
    需要异步执行 有返回值 的任务时(如计算、查询、IO 操作)。
  • 优势
    支持链式调用、异常处理、任务组合(如 thenCombineallOf),比传统 Future 更灵活。
  • 注意事项
    避免在主线程直接调用 get()(会阻塞),推荐使用回调(thenAccept/thenApply)。
posted @ 2025-06-05 23:34  258333  阅读(52)  评论(0)    收藏  举报