如何在循环中调用可完成的未来并合并所有结果?
问题描述:
我正试图实现这样的事情。这是一个表达意图的例子。如何在循环中调用可完成的未来并合并所有结果?
我希望所有完整的期货能够执行并将所有结果合并到一个结果并返回。因此,对于下面的示例,集合allResults应该包含字符串“one”,“two”,“three”,每个3次。我希望他们都能并行运行而不是连续运行。
任何指向我可以用来实现这一目标的可补充未来的API的指针都是非常有用的。
public class Main {
public static void main(String[] args) {
int x = 3;
List<String> allResuts;
for (int i = 0; i < x; i++) {
//call getCompletableFutureResult() and combine all the results
}
}
public static CompletableFuture<List<String>> getCompletableFutureResult() {
return CompletableFuture.supplyAsync(() -> getResult());
}
private static List<String> getResult() {
List<String> list = new ArrayList<>();
list.add("one");
list.add("two");
list.add("three");
return list;
}
}
答
不能收集结果在第一for
循环,因为这将意味着你甚至没有启动其他任务,同时等待前面的任务的结果。
因此,一旦所有任务开始,就开始收集结果。
public static void main(String[] args) throws Exception
{
int x = 3;
Queue<CompletableFuture<List<String>>> cfs = new ArrayDeque<>(x);
for (int i = 0; i < x; i++)
{
cfs.add(getCompletableFutureResult());
}
List<String> allResuts = new ArrayList<>();
for (CompletableFuture<List<String>> cf : cfs)
allResuts.addAll(cf.get());
System.out.println(allResuts);
}
答
有来自文卡塔拉朱答案的问题。 Raju使用得到调用将来这是一个阻塞调用,并杀死了Async风格编码的主要目的。总是避免做期货。
有大量内置的方法建立一个围绕处理像thenApply,thenAccept,thenCompose,thenCombine等
CompletableFuture.allOf
方法是指当你不得不处理多个期货使用未来值。
它具有这样的签名如下
public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs)
旁注:CompletableFuture.anyOf
可以当你只关心未来第一完成使用。当您需要完成所有期货时,请使用allOf
。
我会使用CompletableFuture.allOf按以下方式编码您的规范。
public class DorjeeTest {
public static CompletableFuture<List<String>> getCompetableFutureResult() {
return CompletableFuture.supplyAsync(() -> getResult());
}
public static List<String> getResult() {
return Lists.newArrayList("one", "two", "three");
}
public static void testFutures() {
int x = 3;
List<CompletableFuture<List<String>>> futureResultList = Lists.newArrayList();
for (int i = 0; i < x; i++) {
futureResultList.add(getCompetableFutureResult());
}
CompletableFuture[] futureResultArray = futureResultList.toArray(new CompletableFuture[futureResultList.size()]);
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(futureResultArray);
CompletableFuture<List<List<String>>> finalResults = combinedFuture
.thenApply(voidd ->
futureResultList.stream()
.map(future -> future.join())
.collect(Collectors.toList()));
finalResults.thenAccept(result -> System.out.println(result));
}
public static void main(String[] args) {
testFutures();
System.out.println("put debug break point on this line...");
}
}
定义_combine_。 –