CompletableFuture处理超时
在当前的 BatchProcessingService 类中,所有异步任务均通过 CompletableFuture.supplyAsync() 提交,并使用了自定义的 taskExecutor 执行器。但目前 没有实现超时控制,即如果某个任务长时间不完成,也不会中断或返回超时结果。
public void processWithTimeout(BatchRequest request, Consumer<ProcessResult> callback, CompletableFuture<ProcessResult> completableFuture) { CompletableFuture<ProcessResult> future = CompletableFuture.supplyAsync( () -> businessService.dealBusiness(request), taskExecutor); // 超时 future CompletableFuture<ProcessResult> 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的请求参数如下:
[{ "id":"1" }, { "id":"2" }, { "id":"3" }, { "id":"999" }]
- id为999的数据为超时处理
- 模拟超时的业务代码如下所示:
// 模拟处理逻辑 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 ); } }

完整代码见上一篇博文

浙公网安备 33010602011771号