Java 不同类型的 ExecutorService invokeAll
Java ExecutorService invokeAll with different types
我正在使用 Java 1.7.
我正在尝试同时执行两种方法。但是,每种方法都有不同的 return 类型。
我有以下内容:
private ExecutorService executorService = Executors.newFixedThreadPool(2);
private void executeConcurrentTasks(final boolean autoBookingEnabled, final TripDTO tripDTO, final ApprovalRequestDetails approvalRequestDetails, final ApprovalRequest approvalRequest, final QuoteResponse quoteResponse, final TripRequirementsResponse tripRequirementsResponse, final List<List<Evaluator>> evaluatorsList, final List<EvaluationApprovalTree> evaluationTree, final Long memberId, final Map<String,Object> properties, final HttpSession session) {
List<Callable<?>> tasks = Arrays.asList(
new Callable<BookServicesResponse>() {
public BookServicesResponse call() throws Exception {
BookServicesResponse autoBookResponse = bookServices(autoBookingEnabled, tripDTO, approvalRequestDetails, approvalRequest, quoteResponse, memberId, properties, session);
return autoBookResponse;
}
},
new Callable<ApprovalResponse>() {
public ApprovalResponse call() throws Exception {
ApprovalResponse approvalResponse = submitApproval(approvalRequest, tripDTO, tripRequirementsResponse, evaluatorsList, evaluationTree, memberId, properties, session);
return approvalResponse;
}
});
List<Future<?>> futures = executorService.invokeAll(tasks); // compile error
for (Future<?> future : futures) {
try {
Object obj = future.get();
if (obj instanceof BookServicesResponse) {
// ...
} else if (obj instanceof ApprovalResponse) {
// ...
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
编译错误:
问题
是否有一种通用的方法来处理这两种方法的调用,以便 returned 的期货列表每个都有不同的对象?
我不知道这是否是最佳解决方案,它实际上并没有回答如何使用泛型来获得不同可调用对象列表的问题。但我最终使用了两个单独的 Callables 和 Futures。
Callable<BookServicesResponse> taskBook = new Callable<BookServicesResponse>() {
public BookServicesResponse call() throws Exception {
BookServicesResponse autoBookResponse = bookServices(autoBookingEnabled, tripDTO, approvalRequestDetails, approvalRequest, quoteResponse, memberId, properties, session);
return autoBookResponse;
}
};
Callable<ApprovalResponse> taskApprove = new Callable<ApprovalResponse>() {
public ApprovalResponse call() throws Exception {
ApprovalResponse approvalResponse = submitApproval(approvalRequest, tripDTO, tripRequirementsResponse, evaluatorsList, evaluationTree, memberId, properties, session);
return approvalResponse;
}
};
Future<BookServicesResponse> futureBook = executorService.submit(taskBook);
Future<ApprovalResponse> futureApprove = executorService.submit(taskApprove);
它无法按照您尝试的方式工作,因为 invokeAll
需要类型为 List<? extends Callable<T>>
而不是 List<? extends Callable<? extends T>>
的参数。您可以认为这是 API.
的缺点
为了解决这个问题,您可以使用 List<Callable<Object>>
或使用 BookServicdsResponse
和 ArrovalResponse
的公共超类(我将在此使用 Response
例如):
List<Callable<Response>> tasks = Arrays.asList(
new Callable<Response>() {
public Response call() throws Exception {
BookServicesResponse autoBookResponse = bookServices(autoBookingEnabled, tripDTO, approvalRequestDetails, approvalRequest, quoteResponse, memberId, properties, session);
return autoBookResponse;
}
},
new Callable<Response>() {
public Response call() throws Exception {
ApprovalResponse approvalResponse = submitApproval(approvalRequest, tripDTO, tripRequirementsResponse, evaluatorsList, evaluationTree, memberId, properties, session);
return approvalResponse;
}
});
List<Future<Response>> futures = executorService.invokeAll(tasks); // compile error
您也可以像这样使用“不安全”转换:
List<Future<?>> futures = executorService.invokeAll((List<Callable<Object>>) tasks);
因为您只会从 Callable
中检索元素,所以这不会导致不需要的 ClassCastException
。
我正在使用 Java 1.7.
我正在尝试同时执行两种方法。但是,每种方法都有不同的 return 类型。
我有以下内容:
private ExecutorService executorService = Executors.newFixedThreadPool(2);
private void executeConcurrentTasks(final boolean autoBookingEnabled, final TripDTO tripDTO, final ApprovalRequestDetails approvalRequestDetails, final ApprovalRequest approvalRequest, final QuoteResponse quoteResponse, final TripRequirementsResponse tripRequirementsResponse, final List<List<Evaluator>> evaluatorsList, final List<EvaluationApprovalTree> evaluationTree, final Long memberId, final Map<String,Object> properties, final HttpSession session) {
List<Callable<?>> tasks = Arrays.asList(
new Callable<BookServicesResponse>() {
public BookServicesResponse call() throws Exception {
BookServicesResponse autoBookResponse = bookServices(autoBookingEnabled, tripDTO, approvalRequestDetails, approvalRequest, quoteResponse, memberId, properties, session);
return autoBookResponse;
}
},
new Callable<ApprovalResponse>() {
public ApprovalResponse call() throws Exception {
ApprovalResponse approvalResponse = submitApproval(approvalRequest, tripDTO, tripRequirementsResponse, evaluatorsList, evaluationTree, memberId, properties, session);
return approvalResponse;
}
});
List<Future<?>> futures = executorService.invokeAll(tasks); // compile error
for (Future<?> future : futures) {
try {
Object obj = future.get();
if (obj instanceof BookServicesResponse) {
// ...
} else if (obj instanceof ApprovalResponse) {
// ...
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
编译错误:
问题
是否有一种通用的方法来处理这两种方法的调用,以便 returned 的期货列表每个都有不同的对象?
我不知道这是否是最佳解决方案,它实际上并没有回答如何使用泛型来获得不同可调用对象列表的问题。但我最终使用了两个单独的 Callables 和 Futures。
Callable<BookServicesResponse> taskBook = new Callable<BookServicesResponse>() {
public BookServicesResponse call() throws Exception {
BookServicesResponse autoBookResponse = bookServices(autoBookingEnabled, tripDTO, approvalRequestDetails, approvalRequest, quoteResponse, memberId, properties, session);
return autoBookResponse;
}
};
Callable<ApprovalResponse> taskApprove = new Callable<ApprovalResponse>() {
public ApprovalResponse call() throws Exception {
ApprovalResponse approvalResponse = submitApproval(approvalRequest, tripDTO, tripRequirementsResponse, evaluatorsList, evaluationTree, memberId, properties, session);
return approvalResponse;
}
};
Future<BookServicesResponse> futureBook = executorService.submit(taskBook);
Future<ApprovalResponse> futureApprove = executorService.submit(taskApprove);
它无法按照您尝试的方式工作,因为 invokeAll
需要类型为 List<? extends Callable<T>>
而不是 List<? extends Callable<? extends T>>
的参数。您可以认为这是 API.
为了解决这个问题,您可以使用 List<Callable<Object>>
或使用 BookServicdsResponse
和 ArrovalResponse
的公共超类(我将在此使用 Response
例如):
List<Callable<Response>> tasks = Arrays.asList(
new Callable<Response>() {
public Response call() throws Exception {
BookServicesResponse autoBookResponse = bookServices(autoBookingEnabled, tripDTO, approvalRequestDetails, approvalRequest, quoteResponse, memberId, properties, session);
return autoBookResponse;
}
},
new Callable<Response>() {
public Response call() throws Exception {
ApprovalResponse approvalResponse = submitApproval(approvalRequest, tripDTO, tripRequirementsResponse, evaluatorsList, evaluationTree, memberId, properties, session);
return approvalResponse;
}
});
List<Future<Response>> futures = executorService.invokeAll(tasks); // compile error
您也可以像这样使用“不安全”转换:
List<Future<?>> futures = executorService.invokeAll((List<Callable<Object>>) tasks);
因为您只会从 Callable
中检索元素,所以这不会导致不需要的 ClassCastException
。