completablefuture.supplyasync() 是异步执行有返回值任务的最直接方式,支持默认或自定义线程池,推荐链式回调(如 thenapply、thenaccept)而非阻塞 get(),需显式处理异常(exceptionally 或 handle),并注意线程安全与 threadlocal 上下文传递问题。

用 CompletableFuture.supplyAsync() 就能异步执行有返回值的任务,它接收一个 Supplier<t></t>,自动在线程池中执行并返回 CompletableFuture<t></t>。
用 supplyAsync 启动带返回值的异步任务
这是最直接的方式。任务逻辑写在 Supplier 里,执行完自动把结果封装进 CompletableFuture:
-
supplyAsync(Supplier):使用默认的ForkJoinPool.commonPool() -
supplyAsync(Supplier, Executor):可指定自定义线程池,更可控(推荐用于 IO 或长时间任务)
例如:
CompletableFutureThread.sleep(1000);
return "Hello from async";
});
获取返回值:不要阻塞,优先用回调
不建议调用 get() 阻塞等待——会失去异步意义。更合理的是链式处理结果:
-
thenApply(Function):同步转换结果,比如把 String 转成大写 -
thenAccept(Consumer):只消费结果,不返回新值(如打印日志) -
thenCompose(Function<t completablefuture>>)</t>:用于返回另一个CompletableFuture的场景(比如异步调用第二个接口)
例如:
future.thenApply(String::toUpperCase).thenAccept(System.out::println);
异常处理不能漏
异步任务抛出异常不会打断主线程,但会存入 future 中。必须显式处理,否则可能静默失败:
-
exceptionally(Function<throwable t>)</throwable>:提供降级值(类似 try-catch 的 catch 块) -
handle(BiFunction<t throwable r>)</t>:统一处理成功和异常两种情况,更灵活
例如:
future.exceptionally(ex -> {System.err.println("Task failed: " + ex.getMessage());
return "fallback result";
});
注意线程上下文与共享变量
异步任务运行在其他线程上,要小心以下几点:
- 局部变量可安全捕获(Java 自动做 effectively final 检查)
- 修改外部对象状态需加锁或用线程安全类型(如
AtomicInteger、ConcurrentHashMap) - 若依赖 ThreadLocal(如用户上下文、事务),默认不会传递;需手动透传或换用支持上下文传播的线程池(如 Spring 的
ThreadPoolTaskExecutor配合ThreadPoolTaskExecutor.setTaskDecorator)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











