如何并行处理多个任务并等待每个任务成功失败

时间:2018-02-07 13:45:20

标签: java threadpool completable-future

我有大约5个与从HTTP获取数据和处理数据以及根据数据生成结果相关的任务。

我想并行运行这些任务,等待所有任务成功完成或其中一个任务失败。每个任务都应该能够发布失败原因。如果其中一个任务失败,那么所有任务都被视为失败并退出而不等待所有任务完成。

我尝试使用可填写的期货和期货清单来实现它,但它不起作用,代码不是发布的好条件。

有没有更好的方法可以实现它?示例将有所帮助。

2 个答案:

答案 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 ServiceCompletable 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,建立一个任务列表并传递给可完成的未来。或者遍历此列表并单独调用每个任务。