java - 谁能举例说明如何在 Java 中的 InvokeAll() Callable 方法中使用 Generic?
问题描述
我有两个单独的任务列表,并希望使用通用/通用方法在 ExecutorService 中使用 invokeAll() 来执行两者。我能够获得每个 TaskList 的响应和 invokeAll() 。但无法编写一个通用的执行并得到结果。
定位用户任务:
List<LocateUser> taskList = new ArrayList<>();
taskList.add(new BSLocateUserClient(url, locateName, username, token));
List<Future<LocateUserResponse>> locateResponse = executor.invokeAll(taskList);
locateResponse.forEach(response -> {
LocateUserResponse user;
try {
user = response.get();
} catch (InterruptedException | ExecutionException e) {
//
} finally {
executor.shutdown();
}
});
登录响应任务:
List<LoginUser> taskList = new ArrayList<>();
for (String url : urls) {
taskList.add(new BSWebserviceClient(url, username, password, isOciLogin22, ociWebServiceTemplateFactory));
}
List<Future<LoginResponse>> response = executor.invokeAll(taskList);
List<LoginResponse> loginResponses = new ArrayList<>();
response.forEach(loginResponse -> {
try {
LoginResponse loginDetails = loginResponse.get();
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
executor.shutdown();
}
});
你能帮我解决这个问题吗?
解决方案
我实现了这一点 - 通过添加一个接口ResponseTask
并将此接口实现到响应类并为 invokeAll 和 getResponse 创建一个通用/通用方法。
public interface ResponseTask extends Serializable {
}
调用全部:
public <T extends ResponseTask> List<T> invokeAll(Set<Callable<ResponseTask>> callables, int threadCount) {
ThreadFactory customThreadfactory = new CustomThreadFactoryBuilder().setNamePrefix("MultiThreadExecutor-Calls")
.setDaemon(false).build();
ExecutorService executor = Executors.newFixedThreadPool(threadCount, customThreadfactory);
try {
List<Future<ResponseTask>> threadResponse = executor.invokeAll(callables);
return getResponse(threadResponse);
} catch (InterruptedException e) {
// Restore interrupted state...
Thread.currentThread().interrupt();
} finally {
executor.shutdown();
}
return Collections.emptyList();
}
获取响应:
public <T extends ResponseTask> List<T> getResponse(List<Future<ResponseTask>> threadResponse) {
List<BSLocateUserResponse> locateResponse = new ArrayList<>();
List<LoginUser> userResponse = new ArrayList<>();
for (Future<ResponseTask> response : threadResponse) {
ResponseTask result = null;
try {
result = response.get();
} catch (ExecutionException e) {
// Todo Need to capture the specific exception to ignore here
LOG.info("Exception : {} occurred when calling multithread ", e.getMessage());
continue;
} catch (InterruptedException e) {
// Restore interrupted state...
Thread.currentThread().interrupt();
}
if (result instanceof BSLocateUserResponse) {
locateResponse.add((BSLocateUserResponse) result);
} else if (result instanceof LoginUser) {
userResponse.add((LoginUser) result);
}
}
if (locateResponse.isEmpty()) {
return (List<T>) userResponse;
}
return (List<T>) locateResponse;
}
推荐阅读
- r - 将前 3 行设置为 R 表中的标题
- c++ - C++ 链接器错误 - 未定义对 `mynamespace::Class::get_field()' 的引用
- amazon-web-services - “第 2 行:此上下文中不允许映射值” 创建 Ingress 资源时
- c# - 通过选中组标题复选框来选择所有组项目
- python - 将 4d 张量切片为较小子张量的 4D 张量(仅在最后 2 维切片)
- mysql - 如何在 MySql 中编写循环
- javascript - React hooks:在子函数内部的 onClick 函数内部更改父函数的状态
- c# - 如何使用 Swashbuckle.AspNetCore 在 Swagger 模式中将自定义泛型类型公开为字符串
- mysql - 为什么用 describe 显示时 int 在 mysql 中没有显示大小;
- xml - 如何打印xml字典值中的所有键