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

仅当前一个期货引发异常时,才执行可完成期货的列表

庄嘉
2023-03-14

我有一个可完成期货的列表,我想从第一个期货开始,如果有任何完成例外,我想尝试列表中的下一个期货,依此类推,直到我耗尽了我所有的期货。如果任何一个期货成功了,我想就此止步,而不使用列表中的下一个期货。我如何做到这一点?到目前为止,我已经尝试过:


for (SampleFutures future : getSampleFutures()) {

    try {
          return future.someMethod();
      } catch (Exception e) {
          log.error("An exception occurred, Will try the next future.", e);
      }
}

但是当我测试这种方法时,我看到当未来完成失败时,会抛出异常,并且不会尝试下一组期货。

编辑:

这就是样本的样子

public class SampleFutureA implements SampleFutures {

    @Override
    public CompletableFuture<SomeOject> someMethod() {
        return CompletableFuture
                .supplyAsync(() -> someOtherMethod())
                .thenApply( ()->anotherMethod())
                .exceptionally(ex -> exceptionHandler(ex));
    }

共有1个答案

戚修雅
2023-03-14

对于这种问题,我建议使用EA Async,因为它提供了一种异步/等待机制,可以很容易地实现它:

应用程序启动时初始化异步:(您也可以预处理应用程序,请阅读文档了解详细信息)

Async.init();

然后按如下方式使用wait():

for (SampleFutures future : getSampleFutures()) {
    try {
        return completedFuture(await(future.someMethod()));
    } catch (Exception e) {
        log.error("An exception occurred, Will try the next future.", e);
    }
}
throw new RuntimeException("All futures failed!");

但是,如果您不能或不想使用它,可以使用递归异步方法实现相同的功能:

private CompletableFuture<SomeObject> processNext(Iterator<SampleFutures> iterator) {
    if (iterator.hasNext()) {
        return iterator.next().someMethod()
                .handle((r, e) -> {
                    if (e != null) {
                        log.error("An exception occurred, Will try the next future.", e);
                        return processNext(iterator);
                    } else {
                        return completedFuture(r);
                    }
                }).thenCompose(c -> c);
    }
    CompletableFuture<SomeObject> allFailed = new CompletableFuture<>();
    allFailed.completeExceptionally(new RuntimeException("All futures failed!"));
    return allFailed;
}

你打电话的

return processNext(getSampleFutures().iterator());

此方法将调用第一个未来,只有当它失败时,它才会递归地异步调用自己,从而调用下一个未来。

不幸的是,我们不得不用hande()来实现它-

 类似资料:
  • 我使用scala futures异步提交了1000份工作。我还实现了一个由并发阻塞队列支持的ThrottledExecutionContext,这样它一次最多只能运行100个作业,并将其余的放入队列中。这是一个阻塞操作,因为它涉及调用第三方服务本身。当其中一个抛出异常时,我需要重试整个操作(1000个作业)或者跳过整个批处理。当某些期货仍在运行时,我不能重试。我有办法知道在任何给定的时间点有多少作

  • Java 8的< code > CompletableFuture . allof(CompletableFuture 如果我的一个期货异常完成,那么< code > completablefuture . allof 会在抛出< code>CompletionException之前等待其余期货完成,还是会取消其余期货? 如果它等待所有期货完成,有没有办法让它在任何期货抛出异常并取消剩余期货时立即

  • 我有一个关于Java流和链式可完成期货如何执行的问题。 我的问题是:如果我运行下面的代码,调用,列表中有10个项目需要大约11秒才能完成(列表中的项目数加1)。这是因为我有两个线程并行工作:第一个执行操作,一旦完成,第二个执行操作,第一个开始处理列表中的下一个项目。 如果我注释掉第36行(),那么方法需要大约20秒才能完成。Thread不平行运行;对于列表中的每个项目,操作完成,然后在处理列表中的

  • 在这种情况下,我的做法是使用 将 转换为 。然后使用 获取结果。但是,可能有一个任务需要很长时间并且超时。在这种情况下,我仍然希望获得其余结果(同时并行运行所有任务)。可能吗?怎么办? 谢谢

  • 假设我有一个抽象的“生产者”实例: 我需要对它产生的每个(或一些)对象进行一些处理。所以,我做了类似的事情: …并以<code>Future[Seq[Future[T]]]结束。这没关系,但有点麻烦。我想摆脱外部的,只需要就可以了,但我想不出一个(非阻塞)转换,可以让我这样做。 有什么想法吗?

  • 现在我想让所有的期货最多等待n秒,直到全部完成。我知道我可以调用,但是如果我在循环中对我的所有期货顺序地调用它,则超时开始增加。伪代码: 块会出现超时,直到结果就绪。因此,如果第一个在超时之前完成,第二个也在超时之前完成,依此类推,则整个执行时间最多为而不是。 因此,我正在寻找一个方法,它接受的列表和一个超时,并行运行所有的结果,然后返回一个未来结果的集合。有什么想法吗?