【问题标题】:How Can I skip futures which are completing exceptionally如何跳过异常完成的期货
【发布时间】:2020-04-04 18:48:39
【问题描述】:

下面的代码 sn-p 巩固可完成的未来。下面的问题是我的一些期货异常完成,所以总的来说我的结果异常完成。

从 java 文档中我了解到,当任何未来抛出异常时,allof 都会返回异常 “返回一个新的 CompletableFuture,它在所有给定的 CompletableFuture 完成时完成。如果任何给定的 CompletableFuture 异常完成,则返回的 CompletableFuture 也会这样做,并带有一个 CompletionException 将此异常作为其原因。”

但我没有看到任何其他 api 可以帮助我在一切完成后获得未来

有人可以帮助我或任何线索我如何跳过异常完成的期货。换句话说,我想获得无例外地完成的期货。

CompletableFuture<List<Pair<ExtensionVO, GetObjectResponse>>> result =
          CompletableFuture.allOf(
                  completableFutures.toArray(new CompletableFuture<?>[completableFutures.size()]))
              .thenApply(
                  v ->
                      completableFutures
                          .stream()
                          .map(CompletableFuture::join)
                          .filter(Objects::nonNull) 
                          .collect(Collectors.toList()));

【问题讨论】:

标签: java concurrency completable-future


【解决方案1】:

首先,您必须使用handle 链接一个即使在异常情况下也能产生结果的函数,然后,在调用join() 之前使用.filter(f -&gt; !f.isCompletedExceptionally()) 跳过异常完成的期货:

CompletableFuture<List<Pair<ExtensionVO, GetObjectResponse>>> result =
    CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture<?>[0]))
        .handle((voidResult,throwable) ->
            completableFutures
                    .stream()
                    .filter(f -> !f.isCompletedExceptionally())
                    .map(CompletableFuture::join)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList()));

原则上,您可以使用throwable 来判断是否发生异常,仅在必要时执行isCompletedExceptionally() 检查:

CompletableFuture<List<Pair<ExtensionVO, GetObjectResponse>>> result =
    CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture<?>[0]))
        .handle((voidResult, throwable) ->
            (throwable == null?
                completableFutures.stream():
                completableFutures.stream().filter(f -> !f.isCompletedExceptionally()))
            .map(CompletableFuture::join)
            .filter(Objects::nonNull)
            .collect(Collectors.toList()));

但这可能只会为非常大的列表带来回报,如果有的话。

【讨论】:

    猜你喜欢
    • 2023-04-02
    • 2013-06-29
    • 1970-01-01
    • 2015-08-24
    • 2017-09-30
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多