使用ExecutorCompletionService执行对不同依赖项的并发调用

时间:2018-03-27 20:17:50

标签: java multithreading

我正在尝试使用ExecutorCompletionService - https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorCompletionService.html来尝试对两个不同的依赖包执行并发调用。

我使用ExecutorCompletionService的原因是因为我想比较两个依赖项返回的结果,然后根据特定需求发出一个指标。

我的代码如下所示:

@Builder
@Slf4j
public class TestClass {

    @NonNull private final ExecutorService threadPool = Executors.newFixedThreadPool(2);
    @NonNull private final ExecutorCompletionService<ResultStructure1> dependency1Thread = new ExecutorCompletionService<>(threadPool);
    @NonNull private final ExecutorCompletionService<ResultStructure2> dependency2Thread = new ExecutorCompletionService<>(threadPool);

    public void myMethod() {

        RequestObject1 firstDependencyRequest = RequestObject1.builder()
                .attribute1("someValue")
                .attribute2("secondValue");

        RequestObject2 secondDepdencyRequest = RequestObject1.builder()
                .attribute1("depdency2Value")
                .attribute2("depdency2Secondvalue");

        dependency1Thread.submit(() -> dependency1Client1.call(firstDependencyRequest));
        dependency2Thread.submit(() -> dependencyClient2.call(secondDepdencyRequest));

        final Future<ResultStructure1> future1 = dependency1Thread.take();
        final Future<ResultStructure2> future2 = dependency2Thread.take();
        try {
            ResultStructure1 = future1.get();
            ResultStructure2 = future2.get();
        } catch (ExecutionException e) {
            log.error("Exception calling dependency", e);
            throw e;
        }
    }
}

这是将ExecutorCompletionService用于不同依赖项的正确方法吗?有没有办法拥有一个executorService并从中调用两个依赖项?

1 个答案:

答案 0 :(得分:0)

  

这是使用ExecutorCompletionService的正确方法吗?   不同的依赖?

不幸的是,没有。在等待执行并且结果可用时,您通常会使用它来执行返回相似类型结果的任务。在内部,它使用BlockingQueue,在任务完成时添加Future,然后通过阻塞take方法返回。

因此,如果您确实想使用ExecutorCompletionService,则必须为ResultStructure1ResultStructure2提供基础/公共类型(即{{} 1}}),并声明如下的完成服务 -

ResultStructure

然后 -

private final ExecutorCompletionService<ResultStructure> completionService = 
    new ExecutorCompletionService<>(threadPool)

然后,您可以使用屏蔽completionService.submit(() -> dependency1Client1.call(firstDependencyRequest)); completionService.submit(() -> dependencyClient2.call(secondDepdencyRequest)); 方法 -

等待其结果可用
take

请注意,此时,我们无法找出哪个Future<ResultStructure> result1 = completionService.take(); Future<ResultStructure> result2 = completionService.take(); 代表哪种具体结果类型。所以你无法比较结果。

我的建议是直接使用ExecutorService。