completablefuture.supplyasync 通过 supplier 封装耗时操作,交由 forkjoinpool(或自定义线程池)异步执行,并用 thenapply(同步转换)、thencompose(扁平化嵌套异步)、exceptionally/handle(异常处理)、thenaccept/whencomplete(完成回调)构建非阻塞、可组合的异步链。

使用 CompletableFuture.supplyAsync 开启异步链式调用,核心是把耗时操作封装为 Supplier,交由 ForkJoinPool 公共线程池(或自定义线程池)执行,并通过 thenApply、thenCompose、thenAccept 等方法串联后续逻辑,实现非阻塞、可组合的异步流程。
supplyAsync 基础用法:启动异步任务
supplyAsync 接收一个 Supplier<t></t>,返回 CompletableFuture<t></t>。它默认使用 ForkJoinPool.commonPool(),适合 CPU 密集型小任务;若涉及 I/O(如数据库、HTTP),建议传入自定义线程池避免阻塞公共池。
- 基本写法:CompletableFuture
future = CompletableFuture.supplyAsync(() -> "Hello"); - 指定线程池:ExecutorService ioPool = Executors.newFixedThreadPool(10);
CompletableFuturefuture = CompletableFuture.supplyAsync(() -> fetchData(), ioPool);
用 thenApply 实现同步转换
thenApply 在前序异步结果完成**后立即执行**(同一线程,默认在 supplyAsync 的执行线程上),适用于纯计算、无阻塞的转换操作,返回新的 CompletableFuture。
- 示例:CompletableFuture
length = CompletableFuture.supplyAsync(() -> "world")
.thenApply(s -> s.length()); // 异步获取字符串长度 - 注意:不要在
thenApply中做 sleep、DB 查询等阻塞操作,否则会拖慢整个线程池。
用 thenCompose 衔接下一个异步任务
当后续步骤本身也返回 CompletableFuture(比如又调一次 HTTP 请求),必须用 thenCompose 而不是 thenApply,否则会导致嵌套类型(CompletableFuture<completablefuture>></completablefuture>)。
- 正确写法:CompletableFuture
userFuture = CompletableFuture.supplyAsync(() -> getUserId())
.thenCompose(id -> CompletableFuture.supplyAsync(() -> fetchUserById(id))); // 扁平化链式异步 - 错误写法:
thenApply(id -> CompletableFuture.supplyAsync(...))→ 得到的是CompletableFuture<completablefuture>></completablefuture>,需额外join()或thenCompose(Function.identity())才能解包。
异常处理与完成回调
链式调用中任一环节抛异常,后续 thenApply/thenCompose 不会执行。需用 exceptionally 或 handle 捕获;用 thenAccept 或 whenComplete 做最终通知(无论成功失败)。
- 容错处理:future.thenApply(this::process)
.exceptionally(ex -> { log.error("处理失败", ex); return fallbackValue; }); - 最终通知:future.thenApply(this::process)
.thenAccept(result -> System.out.println("完成:" + result))
.exceptionally(ex -> { System.err.println("失败:" + ex); return null; });










