completeontimeout 用于在 completablefuture 超时未完成后,自动使用指定的默认值完成该 future。具体做法是调用 supplyasync 或 runasync 获取异步任务后,链式调用 .completeontimeout(defaultvalue, timeout, executor)。这样当任务执行时间超过设定的 timeout 时,future 将不再等待原任务结果,而是立即以 defaultvalue 结束;若任务在超时前正常返回,则忽略此方法设置的默认值。

如何设置超时时间和默认值
通过 completeOnTimeout 可以指定一个静态的默认返回值以及超时时长。该方法接收两个参数:第一个是超时后要返回的默认对象(如 null 或某个实例),第二个是 java.time.Duration 类型的超时时间。第三个参数是可选的 Executor,用于调度超时检查逻辑。如果省略 Executor,默认使用 ForkJoinPool.commonPool()。当异步任务因业务逻辑耗时过长而未能在指定时间内完成时,框架会自动触发超时机制并填充默认值。

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.time.Duration;
public class TimeoutExample {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(2);
// 模拟一个可能超时的任务
CompletableFuture<string> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000); // 模拟耗时操作
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return "Success";
}, executor)
.completeOnTimeout("TimedOut", Duration.ofMillis(1000), executor);
String result = future.get();
System.out.println(result); // 输出: TimedOut
executor.shutdown();
}
}</string>
与 thenApply 结合使用的行为差异
当 completeOnTimeout 触发了默认值后,后续链式调用的 thenApply 或 thenAccept 依然会执行,但传入的值是默认值而非原任务结果。这意味着你可以基于这个默认值进行二次处理,例如记录日志或提供降级逻辑。需要注意的是,如果原任务提前完成,completeOnTimeout 设置的默认值将被忽略,后续处理器将收到真实结果。这种设计允许你在不中断主流程的情况下,为长时间运行的任务提供兜底方案。
掌握 ES6+ 特性,包括 async/await、解构、扩展运算符、箭头函数、Promise、模块、迭代器、生成器以及函数式编程模式,编写简洁高效的 Java

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.time.Duration;
public class ChainExample {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(2);
CompletableFuture<string> future = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(2000); } catch (InterruptedException e) {}
return "RealResult";
}, executor)
.completeOnTimeout("Fallback", Duration.ofMillis(500), executor)
.thenApply(res -> res + "_Processed");
System.out.println(future.get()); // 输出: Fallback_Processed
executor.shutdown();
}
}</string>
超时后原任务是否继续运行
在 completeOnTimeout 触发默认值并完成 Future 后,原始的异步任务并不会被强制中断。它仍然会在后台继续运行直到自然结束。这可能导致资源浪费,因为线程池中的线程仍被占用。如果你需要取消正在运行的任务,应结合 cancel(true) 或使用 orTimeout 方法(Java 9+),后者会在超时时尝试中断任务并直接抛出 TimeoutException,而不是静默替换结果。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










