thenrun用于在completablefuture完成后执行无参无返回的runnable任务,不依赖结果、不改变泛型类型,适合日志或清理等副作用操作;上游异常时不会执行。

thenRun 用于在 CompletableFuture 完成后执行一个无参数、无返回值的 Runnable 任务,它不接收上一个阶段的结果,也不影响后续链式调用的返回值类型。
thenRun 的基本用法
它只关心“前一个异步任务是否完成”,不依赖其结果。适合做日志记录、清理资源、触发通知等副作用操作。
- 语法:
future.thenRun(() -> { /* 无参无返回 */ }); - 不会阻塞主线程,也不改变原 CompletableFuture 的泛型类型(仍为
CompletableFuture<void></void>) - 如果上游异常完成,thenRun 不会执行(除非先用
exceptionally或handle处理)
和 thenAccept / thenApply 的区别
三者都表示“上一阶段完成后执行”,但职责不同:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
thenRun:只执行动作,不读结果,不产新值 → 返回CompletableFuture<void></void> -
thenAccept:消费上一阶段结果(如thenAccept(System.out::println)),不返回新值 → 返回CompletableFuture<void></void> -
thenApply:转换结果(如thenApply(s -> s.length())),返回新值 → 返回CompletableFuture<r></r>
实际使用示例
假设发起一个异步 HTTP 请求,完成后打印日志:
CompletableFuture<string> future = CompletableFuture.supplyAsync(() -> {
// 模拟耗时请求
try { Thread.sleep(1000); } catch (InterruptedException e) {}
return "Hello World";
});
<p>future.thenRun(() -> System.out.println("请求已完成,开始处理后续日志"))
.thenRun(() -> System.out.println("第二条后续动作"));
</p></string>
注意:这两条 thenRun 是串行执行的,且都运行在同一个默认 ForkJoin 线程池中(除非显式指定执行器)。
异常情况下的行为
如果上游 future 因异常而完成(比如 supplyAsync 抛出 RuntimeException),thenRun 将被跳过:
- 不会抛出异常到主线程(除非你主动
join()或get()) - 建议搭配
whenComplete或exceptionally做兜底处理 - 例如:
future.exceptionally(e -> { log.error("失败", e); return null; }).thenRun(...)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










