Java 1.7中ExecutorService invokeAll执行不同返回类型并发任务的实现方法
问题原因
Java 1.7 中 ExecutorService#invokeAll 的方法签名为 <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks),要求集合内所有 Callable 的返回类型一致,你传入的是 List<Callable<?>>,泛型参数无法匹配,因此触发编译错误。
方案1:最小改动适配现有代码
如果不想调整现有遍历判断的逻辑,只要给方法显式指定泛型参数为Object即可解决编译问题:
// 替换原报错行,显式指定泛型类型为Object List<Future<?>> futures = executorService.<Object>invokeAll(tasks);
该方案所有 Callable 的返回值都会向上转型为 Object,和你后续用 instanceof 判断的逻辑完全兼容。
方案2:更安全的泛型实现(推荐)
你只有固定2个不同返回类型的任务,完全可以不用放到同一个 Callable 集合里,分别提交就能拿到明确类型的 Future,不需要做类型判断:
// 分别提交两个任务,拿到明确类型的Future Future<BookServicesResponse> bookFuture = executorService.submit(new Callable<BookServicesResponse>() { @Override public BookServicesResponse call() throws Exception { return bookServices(autoBookingEnabled, tripDTO, approvalRequestDetails, approvalRequest, quoteResponse, memberId, properties, session); } }); Future<ApprovalResponse> approvalFuture = executorService.submit(new Callable<ApprovalResponse>() { @Override public ApprovalResponse call() throws Exception { return submitApproval(approvalRequest, tripDTO, tripRequirementsResponse, evaluatorsList, evaluationTree, memberId, properties, session); } }); // 直接获取对应类型的返回值,不需要instanceof判断 try { BookServicesResponse autoBookResponse = bookFuture.get(); // 处理预订返回逻辑 ApprovalResponse approvalResponse = approvalFuture.get(); // 处理审批返回逻辑 } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); }
该方案完全避免了类型判断,泛型逻辑更严谨,没有运行时类型转换风险。
内容的提问来源于stack exchange,提问作者Richard
相关产品推荐
相关产品推荐

