我有大约5个与从HTTP获取数据和处理数据以及根据数据生成结果相关的任务。
我想并行运行这些任务,等待所有任务成功完成或其中一个任务失败。每个任务都应该能够发布失败原因。如果其中一个任务失败,那么所有任务都被视为失败并退出而不等待所有任务完成。
我尝试使用可填写的期货和期货清单来实现它,但它不起作用,代码不是发布的好条件。
有没有更好的方法可以实现它?示例将有所帮助。
答案 0 :(得分:2)
使用allOf
静态方法或Stream
方法。
方法1: -
CompletableFuture<Void> combinedFuture
= CompletableFuture.allOf(future1, future2, future3);
combinedFuture.get();
static CompletableFuture allOf(CompletableFuture ... cfs) 返回一个新的CompletableFuture,它在所有的时候完成 给予CompletableFutures完成。
在这种方法中,您需要单独获取Future对象的结果并执行进一步处理。
方法2: -
方法2的优点是,假设Future返回String对象,Future结果将被连接并用单个空格分隔。
String combined = Stream.of(future1, future2, future3)
.map(CompletableFuture::join)
.collect(Collectors.joining(" "));
答案 1 :(得分:0)
并行运行任务的最佳方法是将Executor Service与Completable Future一起使用 如果一个任务失败,您必须考虑异常处理。
在这种情况下几乎没有可能:
使用exceptionally()
:
QuoteUtil quoteUtil = new QuoteUtil();
ExecutorService executor = Executors.newWorkStealingPool();
CompletableFuture
.supplyAsync(quoteUtil::emptyQuote, executor)
.thenApply(String::length)
.exceptionally(exception -> "No quote available")
.thenAccept(System.out::println);
executor.shutdown();
executor.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);
使用异常处理程序:
CompletableFuture
.supplyAsync(quoteUtil::emptyQuote, executor)
.thenApply(String::length)
.handle((result, throwable) -> {
if (throwable != null) {
return "No quote available: "
+ throwable;
} else {
return result.toString();
}
})
.thenAccept(System.out::println);
thenApply()
例外:
try {
CompletableFuture
.supplyAsync(quoteUtil::emptyQuote, executor)
.thenApply(String::length)
.thenAccept(System.out::println)
.get();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
executor.shutdown();
}
代码段只显示一个电话。你需要做同样的事情,但需要完成一堆任务。根据他的回答建议notionquest,建立一个任务列表并传递给可完成的未来。或者遍历此列表并单独调用每个任务。