在 Java 8 中并行调用两个函数

Joy*_*Joy 6 java spring multithreading java-8 spring-boot

我的 Spring boot 应用程序中有一个用例,如下所示:

我想id使用以下函数从响应中获取字段值:

String id = getIdFromResponse(response);
Run Code Online (Sandbox Code Playgroud)

如果我在响应中没有得到任何 id,那么我会id使用以下函数检查请求参数中是否存在该字段:

String id = getIdFromRequest(request);
Run Code Online (Sandbox Code Playgroud)

到目前为止,我正在按顺序调用它们。但是我想让这两个函数并行运行,我想在从它们中的任何一个获得 id 后立即停止。

我想知道是否有任何方法可以streams在 Java 8 中使用它来实现这一点。

Lin*_*ica 8

你可以使用这样的东西:

String id = Stream.<Supplier<String>>of(
        () -> getIdFromResponse(response), 
        () -> getIdFromRequest(request)
    )
    .parallel()
    .map(Supplier::get)
    .filter(Objects::nonNull)
    .findFirst()
    .orElseThrow():
Run Code Online (Sandbox Code Playgroud)

需要提供者,因为当您不使用它们时,两个请求仍会按顺序执行。

我还假设您的方法null在未找到任何内容时返回,因此我必须使用.filter(Objects::nonNull).

根据您的用例,您可以替换.orElseThrow()为不同的东西,例如.orElse(null)


Nik*_*las 6

没有必要使用 Stream API,只要存在一个完全适用于此的方法。

ExecutorService::invokeAny(Collection<? extends Callable<T>>)

执行给定的任务,返回成功完成的任务的结果(即,不抛出异常),如果有的话。在正常或异常返回时,未完成的任务将被取消。

List<Callable<String>> collection = Arrays.asList(
    () -> getIdFromResponse(response),
    () -> getIdFromRequest(request)
);

// you want the same number of threads as the size of the collection
ExecutorService executorService = Executors.newFixedThreadPool(collection.size());
String id = executorService.invokeAny(collection);
Run Code Online (Sandbox Code Playgroud)

三注意事项: