简体   繁体   English

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

[英]Use ExecutorCompletionService to perform concurrent calls to different dependencies

I am trying to use the ExecutorCompletionService - https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorCompletionService.html , to try and perform concurrent calls to two different dependent packages. 我正在尝试使用ExecutorCompletionService- https: //docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorCompletionService.html尝试对两个不同的依赖程序包执行并发调用。

The reason I am using ExecutorCompletionService is because I want to compare the results returned by both the dependencies and then emit a metric based on a specific requirement. 我使用ExecutorCompletionService的原因是因为我想比较两个依赖项返回的结果,然后根据特定要求发出指标。

My code looks like this: 我的代码如下所示:

@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;
        }
    }
}

Is this the correct way to be using ExecutorCompletionService for different dependencies? 这是对不同的依赖项使用ExecutorCompletionService的正确方法吗? Is there a way to have a single executorService and have both the dependencies be called from that? 有没有办法拥有一个executorService并从中调用两个依赖项?

Is this the correct way to be using ExecutorCompletionService for different dependencies? 这是对不同的依赖项使用ExecutorCompletionService的正确方法吗?

Unfortunately, no. 抱歉不行。 You'd typically use it to execute tasks returning similar type of results while you wait for their execution and their results to be available. 您通常会用它来执行返回相似类型结果的任务,同时等待其执行结果可用。 Internally it uses a BlockingQueue where it adds the Future s as the tasks complete, which is then returned by its blocking take method. 在内部,它使用BlockingQueue在完成任务时在其中添加Future ,然后由其blocking take方法返回。

So, if you do want to use an ExecutorCompletionService , you'd have to come up with a base/common type for ResultStructure1 and ResultStructure2 (ie, ResultStructure ), and declare a completion service like below - 因此,如果您确实想使用ExecutorCompletionService ,则必须为ResultStructure1ResultStructure2 (即ResultStructure )提供一个基本/通用类型,并声明如下的完成服务-

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

and then - 接着 -

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

You can then wait for their results to be available using the blocking take method - 然后,您可以使用“阻止take方法等待其结果可用-

Future<ResultStructure> result1 = completionService.take();
Future<ResultStructure> result2 = completionService.take();

Please note that at this point, we have no way of finding out which Future represents which concrete result type. 请注意,目前,我们无法找出哪种Future代表哪种具体结果类型。 So you have no way of comparing the results. 因此,您无法比较结果。

My recommendation would be to simply use ExecutorService directly. 我的建议是直接使用ExecutorService。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM