大佬教程收集整理的这篇文章主要介绍了清单 走向未来 序列,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
用途CompletableFuture.allOf(...)
:
static<T> CompletableFuture<List<T>> sequence(List<CompletableFuture<T>> com) {
return CompletableFuture.allOf(com.toArray(new CompletableFuture<?>[0]))
.thenApply(v -> com.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList())
);
}
关于您的实现的一些评论:
您使用的.thenComposeAsync
,.thenApplyAsync
并且.thenCombineAsync
很可能没有做你的期望。这些...Async
方法在单独的线程中运行提供给它们的函数。因此,在您的情况下,您导致将新项添加到列表中以在提供的执行程序中运行。无需将轻量级操作填充到缓存的线程执行器中。请勿在thenXXXXAsync
无充分理由的情况下使用方法。
另外,reduce
不应用于堆积到易变容器中。即使在流是顺序的流时它可能正确工作,但是如果将流设为并行流,它将失败。要执行可变减少,请.collect
改用。
如果要在第一次失败后立即异常完成整个计算,请在您的sequence
方法中执行以下操作:
CompletableFuture<List<T>> result = CompletableFuture.allOf(com.toArray(new CompletableFuture<?>[0]))
.thenApply(v -> com.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList())
);
com.forEach(f -> f.whenComplete((t, eX) -> {
if (ex != null) {
result.completeExceptionally(eX);
}
}));
return result;
此外,如果您想在第一次失败时取消其余操作,请在exec.shutdownNow();
之后添加result.completeExceptionally(eX);
。当然,这假定exec
仅针对这一计算存在。如果没有,则必须循环遍历并分别取消剩余的Future
每个。
我正在尝试转换List<CompletableFuture<X>>
为CompletableFuture<List<T>>
。当您有许多异步任务并且需要获得所有异步任务的结果时,这非常有用。
如果它们中的任何一个失败,那么最终的未来将失败。这就是我实现的方式:
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),(a,b) -> a.thenCombineAsync(b,(ls1,ls2)-> {
ls1.addAll(ls2);
return ls1;
},exeC));
}
要运行它:
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);
如果其中任何一个失败,则失败。即使有一百万个期货,它也能提供预期的输出。我的问题是:假设如果有超过5000个期货,并且其中任何一个失败,我都会得到StackOverflowError
:
我做错了什么?
注意:当任何将来失败时,上述返回的将来都会失败。接受的答案也应考虑这一点。
以上是大佬教程为你收集整理的清单 走向未来 序列全部内容,希望文章能够帮你解决清单 走向未来 序列所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。