是否存在Java 9 CompletableFuture超时处理(含默认值)的替代方案
Java 8及以下CompletableFuture超时处理替代实现
Java 9及以上的CompletableFuture提供了completeOnTimeout和orTimeout方法直接实现超时逻辑,对于Java 8及以下版本,可以通过结合ScheduledExecutorService和CompletableFuture的状态控制方法实现等效功能。
1. 类似completeOnTimeout:超时返回默认值
该方法会在指定时长后,若原Future仍未完成,则用默认值完成它。
import java.util.concurrent.*; public class CompletableFutureUtils { public static <T> CompletableFuture<T> completeOnTimeout(CompletableFuture<T> future, T defaultValue, long timeout, TimeUnit unit) { // 项目中建议复用全局定时线程池,避免重复创建销毁线程 ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); ScheduledFuture<?> scheduledTask = scheduler.schedule(() -> { // 仅当Future未完成时,用默认值完成它 future.complete(defaultValue); scheduler.shutdown(); }, timeout, unit); // 原Future完成时取消定时任务,释放资源 future.whenComplete((res, ex) -> { scheduledTask.cancel(false); if (!scheduler.isShutdown()) { scheduler.shutdown(); } }); return future; } }
使用示例:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { // 模拟耗时任务 try { Thread.sleep(2000); } catch (InterruptedException e) { throw new RuntimeException(e); } return "正常结果"; }); // 设置1秒超时,超时返回"默认值" CompletableFuture<String> timeoutFuture = CompletableFutureUtils.completeOnTimeout(future, "默认值", 1, TimeUnit.SECONDS); System.out.println(timeoutFuture.get()); // 输出"默认值"
2. 类似orTimeout:超时抛出异常
该方法会在指定时长后,若原Future仍未完成,则抛出TimeoutException。
import java.util.concurrent.*; public class CompletableFutureUtils { public static <T> CompletableFuture<T> orTimeout(CompletableFuture<T> future, long timeout, TimeUnit unit) { ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); ScheduledFuture<?> scheduledTask = scheduler.schedule(() -> { // 仅当Future未完成时,抛出超时异常 future.completeExceptionally(new TimeoutException(String.format("Future超时:%d %s", timeout, unit.name().toLowerCase()))); scheduler.shutdown(); }, timeout, unit); // 原Future完成时取消定时任务 future.whenComplete((res, ex) -> { scheduledTask.cancel(false); if (!scheduler.isShutdown()) { scheduler.shutdown(); } }); return future; } }
使用示例:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(2000); } catch (InterruptedException e) { throw new RuntimeException(e); } return "正常结果"; }); try { // 设置1秒超时 String result = CompletableFutureUtils.orTimeout(future, 1, TimeUnit.SECONDS).get(); } catch (InterruptedException | ExecutionException e) { // 捕获超时异常 if (e.getCause() instanceof TimeoutException) { System.out.println("任务超时:" + e.getCause().getMessage()); } }
关键注意事项
- 线程池复用:示例中使用
newSingleThreadScheduledExecutor仅为演示,实际项目中应复用全局的ScheduledExecutorService,减少线程创建销毁的开销。 - 状态原子性:
CompletableFuture的complete和completeExceptionally方法是原子操作,只会在Future未完成时生效,不会覆盖已完成的结果或异常。 - 资源释放:通过
whenComplete回调取消定时任务并关闭线程池,避免资源泄漏。
内容的提问来源于stack exchange,提问作者AP_22
相关产品推荐
相关产品推荐

