Java 8 - 并行调用异步方法并合并它们的结果
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42504277/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java 8 - Call methods async in parallel and combine their results
提问by saw303
I am new to the Java 8 concurrency features such as CompletableFuture
and I hope you can help to get started with the following use case.
我是 Java 8 并发功能的新手,例如CompletableFuture
,我希望您能帮助您开始使用以下用例。
There is a service called TimeConsumingServices
that provides time consuming operations which I'd like to run in parallel since all of them are independent.
有一个服务称为TimeConsumingServices
提供耗时的操作,我想并行运行这些操作,因为它们都是独立的。
interface TimeConsumingService {
default String hello(String name) {
System.out.println(System.currentTimeMillis() + " > hello " + name);
return "Hello " + name;
}
default String planet(String name) {
System.out.println(System.currentTimeMillis() + " > planet " + name);
return "Planet: " + name;
}
default String echo(String name) {
System.out.println(System.currentTimeMillis() + " > echo " + name);
return name;
}
default byte[] convert(String hello, String planet, String echo) {
StringBuilder sb = new StringBuilder();
sb.append(hello);
sb.append(planet);
sb.append(echo);
return sb.toString().getBytes();
}
}
So far I implemented the following example and I have managed to call all three service methods in parallel.
到目前为止,我实现了以下示例,并且已设法并行调用所有三个服务方法。
public class Runner implements TimeConsumingService {
public static void main(String[] args) {
new Runner().doStuffAsync();
}
public void doStuffAsync() {
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> this.hello("Friend"));
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> this.planet("Earth"));
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> this.echo("Where is my echo?"));
CompletableFuture.allOf(future1, future2, future3).join();
}
}
Is there a way to collect the return values of each service call and invoke the method byte[]‘ convert(String, String, String)
?
有没有办法收集每个服务调用的返回值并调用该方法byte[]‘ convert(String, String, String)
?
回答by Ash
To combine the result after you have returned them all you can do something like this
要在返回结果后合并所有结果,您可以执行以下操作
CompletableFuture<byte[]> byteFuture = CompletableFuture.allOf(cf1, cf2, cf3)
.thenApplyAsync(aVoid -> convert(cf1.join(), cf2.join(), cf3.join()));
byte[] bytes = byteFuture.join();
This will run all of your futures, wait for them all to complete, then as soon as they are all finished will call your convert
method you mention.
这将运行您所有的期货,等待它们全部完成,然后一旦它们全部完成,就会调用您convert
提到的方法。
回答by user2377971
After join you can simply get()
values from future1
like:
加入后,您可以简单地使用以下get()
值future1
:
String s1 = future1.get()
and so on
等等
回答by MBec
You can combine them using thenCombine()
method if there is only 3 futures to complete:
thenCombine()
如果只有 3 个期货要完成,您可以使用方法将它们组合起来:
final CompletableFuture<byte[]> byteFuture = future1.thenCombine(future2, (t, u) -> {
StringBuilder sb = new StringBuilder();
sb.append(t);
sb.append(u);
return sb.toString();
}).thenCombine(future3, (t, u) -> {
StringBuilder sb = new StringBuilder();
sb.append(t);
sb.append(u);
return sb.toString();
}).thenApply(s -> s.getBytes());
try {
final byte[] get = byteFuture.get();
} catch (InterruptedException | ExecutionException ex) {
}