CompletableFuture超时后怎么取消当前任务
时间: 2025-01-23 10:11:33 浏览: 18
Java CompletableFuture 超时取消任务的方法
在 JDK 8 的 CompletableFuture
设计中,并未提供直接用于超时后自动取消任务的功能[^1]。然而,可以通过组合多个 API 来实现这一需求。
使用 orTimeout
对于更高版本的 JDK (9+) 用户可以直接利用 orTimeout(long timeout, TimeUnit unit)
方法来设置一个最大等待时间。如果超过指定的时间,则会抛出 TimeoutException 并标记该 Future 已经失败:
public static void exampleOrTimeout() {
try {
CompletableFuture.supplyAsync(() -> {
// Simulate long running task
Thread.sleep(5000);
return "Result";
}).orTimeout(2, TimeUnit.SECONDS).join();
} catch (CompletionException e) {
if(e.getCause() instanceof TimeoutException){
System.out.println("Task timed out");
}
}
}
自定义超时机制
针对 JDK 8 或者希望更灵活控制的情况,可以创建一个新的 CompletableFuture
表达超时逻辑并与原任务关联起来形成竞争关系。当任一条件满足时即触发后续动作。这里展示了一个基于 completeOnTimeout()
和 whenComplete()
组合使用的例子[^2]:
private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
// 定义辅助方法failAfter模拟超时行为
static CompletableFuture<Void> failAfter(Duration duration) {
CompletableFuture<Void> future = new CompletableFuture<>();
scheduler.schedule(
() -> future.completeExceptionally(new RuntimeException("timed out")),
duration.toMillis(),
MILLISECONDS);
return future;
}
public static void customTimeoutExample(){
Duration maxDuration = Duration.ofSeconds(2L);
CompletableFuture<String> resultFuture = CompletableFuture.supplyAsync(() -> {
// 模拟耗时较长的任务
try{Thread.sleep(5000);}catch(Exception ignore){}
return "Completed Task!";
});
// 将实际业务逻辑与自定义超时策略绑定在一起
CompletableFuture<Object> combinedFutures = resultFuture.applyToEither(failAfter(maxDuration), Function.identity());
combinedFutures.whenComplete((result, exception)->{
if(exception != null && exception.getMessage().equals("timed out")){
System.out.println("Operation has been cancelled due to timeout.");
// 这里还可以尝试调用cancel(true),但是需要注意这并不能保证立即终止线程上的工作
resultFuture.cancel(true);
}else{
System.out.println(result);
}
});
}
通过这种方式可以在一定程度上达到预期效果——即使无法强制停止正在运行中的线程,也能及时感知到超时并采取相应措施处理结果或清理资源。
阅读全文
相关推荐


















