Ich versuche zu konvertieren List<CompletableFuture<X>>
zu CompletableFuture<List<T>>
. Dies ist sehr nützlich, wenn Sie viele asynchrone Aufgaben haben und Ergebnisse von allen erhalten möchten.
Wenn einer von ihnen fehlschlägt, schlägt die endgültige Zukunft fehl. So habe ich implementiert:
public static <T> CompletableFuture<List<T>> sequence2(List<CompletableFuture<T>> com, ExecutorService exec) {
if(com.isEmpty()){
throw new IllegalArgumentException();
}
Stream<? extends CompletableFuture<T>> stream = com.stream();
CompletableFuture<List<T>> init = CompletableFuture.completedFuture(new ArrayList<T>());
return stream.reduce(init, (ls, fut) -> ls.thenComposeAsync(x -> fut.thenApplyAsync(y -> {
x.add(y);
return x;
},exec),exec), (a, b) -> a.thenCombineAsync(b,(ls1,ls2)-> {
ls1.addAll(ls2);
return ls1;
},exec));
}
Um es auszuführen:
ExecutorService executorService = Executors.newCachedThreadPool();
Stream<CompletableFuture<Integer>> que = IntStream.range(0,100000).boxed().map(x -> CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep((long) (Math.random() * 10));
} catch (InterruptedException e) {
e.printStackTrace();
}
return x;
}, executorService));
CompletableFuture<List<Integer>> sequence = sequence2(que.collect(Collectors.toList()), executorService);
Wenn einer von ihnen fehlschlägt, schlägt er fehl. Es liefert die erwartete Leistung, selbst wenn es eine Million Futures gibt. Das Problem, das ich habe, ist: Sagen wir, wenn es mehr als 5000 Futures gibt und wenn einer von ihnen fehlschlägt, bekomme ich eine StackOverflowError
:
Ausnahme im Thread "pool-1-thread-2611" java.lang.StackOverflowError unter java.util.concurrent.CompletableFuture.internalComplete (CompletableFuture.java:210) unter java.util.concurrent.CompletableFuture $ ThenCompose.run (CompletableFuture.j : 1487) unter java.util.concurrent.CompletableFuture.postComplete (CompletableFuture.java:193) unter java.util.concurrent.CompletableFuture.internalComplete (CompletableFuture.java:210) unter java.util.concurrent.CompletableFuture CompletableFuture.java:1487)
Was mache ich falsch?
Hinweis: Die oben zurückgegebene Zukunft schlägt sofort fehl, wenn eine der Zukunft fehlschlägt. Die akzeptierte Antwort sollte auch diesen Punkt berücksichtigen.
Collector
stattdessen ein ...