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

等待未来的清单

谢昂雄
2023-03-14

我有一个方法,可以返回期货的列表

List<Future<O>> futures = getFutures();

现在我想等待,直到所有的future都成功完成处理,或者future返回其输出的任何任务抛出异常。即使一项任务引发异常,等待另一项任务也没有意义。

简单的方法是

wait() {

   For(Future f : futures) {
     try {
       f.get();
     } catch(Exception e) {
       //TODO catch specific exception
       // this future threw exception , means somone could not do its task
       return;
     }
   }
}

但这里的问题是,例如,如果第四个期货抛出异常,那么我将不必要地等待前三个期货可用。

如何解决这个问题?会以任何方式倒数闩锁帮助吗?我无法使用FutureisDone,因为java文档说

boolean isDone()
Returns true if this task completed. Completion may be due to normal termination, an exception, or cancellation -- in all of these cases, this method will return true.

共有3个答案

韩彦君
2023-03-14

在Java 8中使用CompletableFuture

    // Kick of multiple, asynchronous lookups
    CompletableFuture<User> page1 = gitHubLookupService.findUser("Test1");
    CompletableFuture<User> page2 = gitHubLookupService.findUser("Test2");
    CompletableFuture<User> page3 = gitHubLookupService.findUser("Test3");

    // Wait until they are all done
    CompletableFuture.allOf(page1,page2,page3).join();

    logger.info("--> " + page1.get());
顾俊茂
2023-03-14

如果您使用的是Java 8,那么使用CompletableFuture和CompletableFuture可以更轻松地实现这一点。allOf,它仅在完成所有提供的CompletableFutures之后应用回调。

// Waits for *all* futures to complete and returns a list of results.
// If *any* future completes exceptionally then the resulting future will also complete exceptionally.

public static <T> CompletableFuture<List<T>> all(List<CompletableFuture<T>> futures) {
    CompletableFuture[] cfs = futures.toArray(new CompletableFuture[futures.size()]);

    return CompletableFuture.allOf(cfs)
            .thenApply(ignored -> futures.stream()
                                    .map(CompletableFuture::join)
                                    .collect(Collectors.toList())
            );
}
蔡弘扬
2023-03-14

一旦期货准备就绪,您可以使用CompletionService接收期货,如果其中一个抛出异常,则取消处理。比如:

Executor executor = Executors.newFixedThreadPool(4);
CompletionService<SomeResult> completionService = 
       new ExecutorCompletionService<SomeResult>(executor);

//4 tasks
for(int i = 0; i < 4; i++) {
   completionService.submit(new Callable<SomeResult>() {
       public SomeResult call() {
           ...
           return result;
       }
   });
}

int received = 0;
boolean errors = false;

while(received < 4 && !errors) {
      Future<SomeResult> resultFuture = completionService.take(); //blocks if none available
      try {
         SomeResult result = resultFuture.get();
         received ++;
         ... // do something with the result
      }
      catch(Exception e) {
             //log
         errors = true;
      }
}

我认为,如果其中一个任务出现错误,您可以进一步改进以取消任何仍在执行的任务。

 类似资料:
  • 问题内容: 我有一种返回List期货的方法 现在,我要等待,直到所有期货都成功完成处理,或者所有由期货返回输出的任务都引发异常。即使一项任务引发异常,也没有必要等待其他期货。 简单的方法是 但是这里的问题是,例如,如果第4个期货抛出异常,那么我将不必要地等待前3个期货可用。 如何解决呢?会以任何方式倒计时闩锁帮助吗?我无法使用Future,isDone因为Java文档说 问题答案: 你可以使用Co

  • 我想运行相同类型的任务(工作线程),但一次不超过一定数量的任务。当任务完成时,其结果是新任务的输入,然后可以启动该任务。 有没有好的方法可以在C 11中使用异步/未来范式来实现这一点? 乍一看,它看起来很简单,你只是生成多个任务: 然后,运行以获取任务的异步结果。 然而,这里的问题是,未来的对象必须存储在某种队列中并一个接一个地等待。但是,可以一遍又一遍地迭代未来的对象,检查它们中的任何一个是否准

  • 我希望像下面这样的代码可以等待这两种未来,但是没有。 我以为< code>seq.onComplete会在完成自身之前等待它们全部完成,但事实并非如此;它会导致: 在scala.concurrent.Future的源代码中有点难以遵循,我想知道如何实现等待(动态大小的)序列的所有原始未来的并行,或者这里可能有什么问题。 编辑:相关问题:https://worldbuilding.stackexch

  • 我正在尝试执行一些相互引用作为外键的查询,因此我必须等到外部未来完成。此算法放置在返回未来的函数中。 运行它时,我得到了这个: === TO CLIENT === 已完成存档 已完成全部 === TO CLIENT === 失败的 单词已完成 的单词 已完成 标记在博客中 完成投票 所以我的问题是,我怎么能等到未来的< code>mysql完成它的“childs”(在< code>whenComp

  • 我想利用Tokio的运行时来处理可变数量的异步期货。由于在编译时期货的计数是未知的,因此 FuturesUnorderd 似乎是我的最佳选择(像 这样的宏需要在编译时指定你的分支;join_all可能是可能的,但是当顺序无关紧要时,文档建议“在很多情况下”FuturesUnordered)。 这个片段的逻辑是一个recv()循环,它被推送到期货桶中,应该一直运行。当新数据到达时,它的解析/处理也被

  • 是否有一种方法可以在不阻塞事件循环的情况下等待一个未来完成? 我知道这个错误通常意味着什么,但我不知道在这种情况下...我试图在谷歌上搜索它,但没有找到任何关于将哪份清单放在哪里的明确解释。和以前一样,除非是强制性的,我更喜欢一次学一件事。 那么,回到这个问题:“基本”Vert.x是否有一种方法可以在事件循环不受干扰的情况下等待未来?