completablefuture核心是通过线程池(默认forkjoinpool.commonpool())异步执行supplyasync(有返回值)或runasync(无返回值)任务,支持自定义线程池、链式回调及异常处理。

CompletableFuture 在 Java 中通过线程池异步执行任务,核心是把任务提交给 Executor(如 ForkJoinPool.commonPool() 或自定义线程池),而不是在当前线程阻塞运行。
用 supplyAsync / runAsync 启动异步任务
这是最常用的方式,底层自动使用默认线程池(ForkJoinPool.commonPool()):
-
supplyAsync:适用于有返回值的任务,返回 CompletableFuture
-
runAsync:适用于无返回值的 Runnable 任务,返回 CompletableFuture
示例:
CompletableFuture<string> future = CompletableFuture.supplyAsync(() -> {
Thread.sleep(1000);
return "Hello from async";
});
CompletableFuture<void> voidFuture = CompletableFuture.runAsync(() -> {
System.out.println("Running asynchronously");
});
</void></string>
指定自定义线程池执行任务
避免挤占公共线程池,尤其在高并发或耗时 I/O 场景下推荐显式传入线程池:
- 使用 supplyAsync(Supplier, Executor) 或 runAsync(Runnable, Executor)
- 常见选择:CachedThreadPool(短任务)、FixedThreadPool(控并发)、或专门的 IO 线程池
示例:
ExecutorService ioPool = Executors.newCachedThreadPool();
CompletableFuture<string> future = CompletableFuture.supplyAsync(() -> {
// 模拟网络请求
return callRemoteApi();
}, ioPool);
</string>
后续操作也默认异步执行
thenApply、thenAccept、thenRun、thenCompose 等“then”系列方法,默认在前一个任务完成的**同一线程**(即任务结束所在线程)上执行——不是调用线程,也不是固定线程池。
- 若需控制后续执行线程,用带 Executor 的重载方法,例如 thenApplyAsync(fn, executor)
- 不加 Async 后缀的方法可能在前序任务线程中同步执行,影响响应性
示例(确保转换逻辑也在 IO 线程池中执行):
future.thenApplyAsync(result -> result.toUpperCase(), ioPool)
.thenAcceptAsync(System.out::println, ioPool);
异常处理与链式健壮性
异步链中任一环节抛异常会导致后续 then 方法跳过,必须显式处理:
- exceptionally(Function):捕获上一阶段的异常,返回默认值
- handle(BiFunction):统一处理结果和异常(无论成功失败都执行)
- whenComplete(BiConsumer):只做副作用(如日志、清理),不改变结果
示例:
future.handle((result, ex) -> {
if (ex != null) {
System.err.println("Failed: " + ex.getMessage());
return "fallback";
}
return result + " processed";
});
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











