找回密码
 立即注册
首页 业界区 业界 CompletableFuture处理超时

CompletableFuture处理超时

眩疝诺 2026-1-18 20:50:00
在当前的 BatchProcessingService 类中,所有异步任务均通过 CompletableFuture.supplyAsync() 提交,并使用了自定义的 taskExecutor 执行器。但目前 没有实现超时控制,即如果某个任务长时间不完成,也不会中断或返回超时结果。
  1. public void processWithTimeout(BatchRequest request,                                   Consumer callback,                                   CompletableFuture completableFuture) {        CompletableFuture future = CompletableFuture.supplyAsync(                () -> businessService.dealBusiness(request), taskExecutor);        // 超时 future        CompletableFuture timeoutFuture = CompletableFuture.supplyAsync(() -> {            try {                return future.get(5, TimeUnit.SECONDS); // 等待最多5秒            } catch (TimeoutException e) {                future.cancel(true); // 尝试取消原任务                throw new CompletionException(new Exception("处理超时"));            } catch (Exception e) {                throw new CompletionException(e);            }        }, taskExecutor);        timeoutFuture.whenComplete((result, throwable) -> {            if (throwable != null) {                ProcessResult errorResult = new ProcessResult(                        request.getId(),                        false,                        "处理失败: " + throwable.getMessage(),                        null,                        0,                        (Exception) throwable.getCause()                );                callback.accept(errorResult);                completableFuture.completeExceptionally(throwable);            } else {                callback.accept(result);                completableFuture.complete(result);            }        });    }
复制代码

  • 手动 get(timeout) 控制增加超时处理
输入API的请求参数如下:
  1. [{    "id":"1"},{    "id":"2"},{    "id":"3"},{    "id":"999"}]
复制代码

  • id为999的数据为超时处理
  • 模拟超时的业务代码如下所示:
  1. // 模拟处理逻辑        String id = request.getId();        Integer idInt = Integer.valueOf(id) == null ? 0 : Integer.valueOf(id);        // 模拟超时:当ID为特定值时,延迟较长时间        if (StringUtils.isNoneBlank(id) && idInt == 999) { // 假设999表示需要超时测试            try {                Thread.sleep(10000); // 模拟10秒超时            } catch (InterruptedException e) {                Thread.currentThread().interrupt();                return new ProcessResult(                        request.getId(),                        false,                        "处理被中断",                        null,                        -1,                        e                );            }        }
复制代码

完整代码见上一篇博文

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册