当前位置: 首页 > 知识库问答 >
问题:

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

霍建章
2023-03-14

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

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

我试图使用完整的未来和未来列表来实现它,但它不起作用,代码也不能很好地发布。

我有没有更好的方法来实现它?以身作则会有所帮助。

共有2个答案

徐学潞
2023-03-14

并行运行任务的最佳方法是使用具有可完成未来的Executor服务
如果一项任务失败,您必须考虑异常处理。

在这种情况下,几乎没有可能:

>

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);

然后应用()异常:

try {
    CompletableFuture
            .supplyAsync(quoteUtil::emptyQuote, executor)
            .thenApply(String::length)
            .thenAccept(System.out::println)
            .get();
} catch (Exception ex) {
    ex.printStackTrace();
} finally {
    executor.shutdown();
}

代码片段只显示一个调用。你也需要做同样的事情,但要完成一系列的任务。建立一份任务清单,并传递给可完成的未来,正如他在回答中所建议的那样。或者遍历这个列表,分别调用每个任务。

岑光熙
2023-03-14

使用allOf静态方法或Stream方法。

方法1:-

CompletableFuture<Void> combinedFuture 
  = CompletableFuture.allOf(future1, future2, future3);

combinedFuture.get(); 

静态CompletableFuture allOf(CompletableFuture... cfs)返回一个新的CompletableFuture,当所有给定的CompletableFutures完成时完成。

在这种方法中,您需要单独获得未来对象的结果,并执行进一步的处理。

方法2:-

方法2中的优点是,假设Future返回String对象,未来的结果由单个空格连接和分隔。

String combined = Stream.of(future1, future2, future3)
  .map(CompletableFuture::join)
  .collect(Collectors.joining(" "));
 类似资料:
  • 我的makefile中的一个目标是一个非常耗时的CPU任务。但是我可以分割工作负载并并行运行任务几次,以加快整个过程。 我的问题是make不会等待所有过程完成。 考虑一下这个简单的脚本,名为“代码> MyTask.SH <代码>: 现在,让我们从bash脚本调用它,并使用等待所有任务完成: 产出如预期: 但是在Makefile中尝试相同的方法时: 它不起作用: 当然,我可以创建多个目标,这些目标可

  • 问题内容: 我有以下使用类的课程。所以我想做的是,在运行cp1实例处理方法的同时,我要并行运行。 但是,我要按顺序cp1,所以我要它运行并完成,如果cp2没有完成或失败,那就很好。如果确实失败,我想加入结果。该示例中未返回任何内容,但我想返回结果。 为此,应该使用TaskExecutor吗?还是线程? 我只希望cp2与cp1并行运行。或者,如果我添加更多内容,例如说cp3,我希望它也可以与cp1并

  • 我在网上搜索了很多关于vs await async,但是在这个特定的使用场景中,我并不真正理解其中的区别。我相信情况很简单。 vs. 其中,是一个异步方法,其中包含一些异步调用,例如使用wait调用db。 问题: 在这种情况下,两者之间有什么区别吗?任何帮助或意见,谢谢!

  • 在C#中,我有以下两个简单的例子: 第一个示例创建一个打印“开始”的任务,等待5秒钟打印“完成”,然后结束任务。我等待任务完成,然后打印“全部完成”。当我运行测试时,它会按预期运行。 第二个测试应该具有相同的行为,只是由于使用了async和Wait,任务内部的等待应该是非阻塞的。但是这个测试只打印“开始”,然后立即打印“全部完成”和“完成”,永远不会打印。 我不知道我为什么会有这样的行为:S非常感

  • 我试着用一个实例并行运行许多计划任务,每一个我这样配置任务 但是有很多实例每秒开始,而第一个实例尚未完成。是否可以同时配置任务运行的一个实例?我的豆子配置在Spring调度器.xml

  • 问题内容: 我想同时下载一些文件,例如100个文件。因此,我决定将下载线程添加到调度队列中,GCD会调整同时运行多少个线程。 这里的问题是:中的块将立即完成,因为它将在另一个线程上运行。因此,如果长度为100,它将立即创建100个线程。 如何配置块以等待下载任务完成?我不想使用,因为它只允许同时运行一个下载任务。 问题答案: 要扩展Abhinav的答案,您应该: 使用创建一个组。 在开始每个下载任