首页 > 解决方案 > 谁能举例说明如何在 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();
    }
});

你能帮我解决这个问题吗?

标签: javaexecutorservice

解决方案


我实现了这一点 - 通过添加一个接口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;
    }

推荐阅读