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

CompletableFuture——快速失败的聚合未来

子车青青
2023-03-14

我一直在使用CompletableFuture.allOf(...)助手来创建聚合期货,只有当它们的复合期货被标记为完成时才会成为“完成”,即:

CompletableFuture<?> future1 = new CompletableFuture<>();
CompletableFuture<?> future2 = new CompletableFuture<>();
CompletableFuture<?> future3 = new CompletableFuture<>();

CompletableFuture<?> future = CompletableFuture.allOf(future1, future2, future3);

我想对这一功能稍作改动,在以下情况下,总的未来市场是完整的:

  • 所有期货均已成功完成或

在后一种情况下,总期货应立即完成(例外),而不必等待其他期货完成,即快速失败。

对比CompletableFuture来说明这一点。allOf(…) 考虑一下:

// First future completed, gotta wait for the rest of them...
future1.complete(null);
System.out.println("Future1 Complete, aggregate status: " + future.isDone());

// Second feature was erroneous! I'd like the aggregate to now be completed with failure
future2.completeExceptionally(new Exception());
System.out.println("Future2 Complete, aggregate status: " + future.isDone());

// Finally complete the third future, that will mark the aggregate as done
future3.complete(null);
System.out.println("Future3 Complete, aggregate status: " + future.isDone());

使用allOf(…) ,此代码生成:

Future1 Complete, aggregate status: false
Future2 Complete, aggregate status: false
Future3 Complete, aggregate status: true

而我的替代聚合实现在Feature2完成后会返回“true”,因为这是一个例外。

我在Java标准库中找不到任何可以帮助我实现这一点的UTIL,这让我感觉很奇怪。。。考虑到这是一个相对普通的用例。

查看CompletableFuture的实现。allOf(…) 很明显,这些场景背后的逻辑相当复杂。我讨厌自己写这篇文章,我想知道是否有其他选择?


共有2个答案

叶琦
2023-03-14

您可以通过创建allOf和anyOf,然后将它们组合成第二个anyOf来做到这一点。

丁立果
2023-03-14

虽然在语法上不如CompletableFuture.allOf(...)方法,但似乎thenCompose(...)可以提供解决方案

CompletableFuture<?> future = future1.thenCompose((f) -> future2).thenCompose((f) -> future3);

这将产生所需的:

Future1 Complete, aggregate status: false
Future2 Complete, aggregate status: true
Future3 Complete, aggregate status: true

这可以包装在一个帮助方法中,该方法将为调用者提供一些语法细节:

private static CompletableFuture<?> composed(CompletableFuture<?> ... futures) {

    // Complete when ALL the underlying futures are completed
    CompletableFuture<?> allComplete = CompletableFuture.allOf(futures);

    // Complete when ANY of the underlying futures are exceptional
    CompletableFuture<?> anyException = new CompletableFuture<>();
    for (CompletableFuture<?> completableFuture : futures) {
        completableFuture.exceptionally((t) -> {
            anyException.completeExceptionally(t);
            return null;
        });
    }

    // Complete when either of the above are satisfied
    return CompletableFuture.anyOf(allComplete, anyException);
}

考虑到:

CompletableFuture<?> future = composed(future1, future2, future3);
 类似资料:
  • 本文向大家介绍svn 清理失败 (cleanup 失败) 的快速解决方法,包括了svn 清理失败 (cleanup 失败) 的快速解决方法的使用技巧和注意事项,需要的朋友参考一下 1、cmd指令,进入.svn目录,找到wc.db文件 sqlite 3 打开 2、 对 svn源代码目录 右键, clean up, 稍等1至5分钟左右,然后会提示 清理成功 以上就是小编为大家带来的svn 清理失败 (

  • 我使用这个查询来查找状态(“Isactive”:false);true或false;还根据状态查找年龄,最后一次计数总额 跟随错误 聚合失败 _geterrorwithcode@src/mongo/shell/utils.js:25:13

  • 我正在尝试使用id字段在我的碎片集合中查找重复项,这是这种模式- 我使用了下面的查询,但收到了“异常:超出$group的内存限制,但不允许外部排序。通过allowDiskUse:true选择加入。”错误,尽管我在查询中使用了“allowDiskUse:true”。 有没有其他方法可以得到我想要的,或者我应该在上面的查询中传递其他东西?谢谢。

  • 1 谱聚类算法的原理   在分析快速迭代聚类之前,我们先来了解一下谱聚类算法。谱聚类算法是建立在谱图理论的基础上的算法,与传统的聚类算法相比,它能在任意形状的样本空间上聚类且能够收敛到全局最优解。 谱聚类算法的主要思想是将聚类问题转换为无向图的划分问题。 首先,数据点被看做一个图的顶点v,两数据的相似度看做图的边,边的集合由$E=A_{ij}$表示,由此构造样本数据集的相似度矩阵A,并求出拉普拉斯

  • 本文向大家介绍Mysql 安装失败的快速解决方法,包括了Mysql 安装失败的快速解决方法的使用技巧和注意事项,需要的朋友参考一下 在安装mysql的过程中,出现的最麻烦的问题和解决方法 安装后,启动不成功,就卡了,程序就没有响应。 如何解决: 找到mysql安装目录下的 该目录就是用来存放我们将来创建的数据库和表的目录, 你只需要将 C:/ProgramData/MySQL/MySQL Serv

  • 主要内容:1 ArrayList的概述,2 ArrayList的源码解析,2.1. 主要类属性,2.2 构造器与初始化容量,2.3 add方法与扩容机制,2.4 addAll方法,2.5 remove方法,2.6 get方法,2.7 set方法,2.8 clone方法,2.9 序列化,2.10. 其他方法,3 迭代器,3.1 Iterator迭代器,3.2 ListIterator列表迭代器,4 快速失败(fail-fast)与安全失败(fail-safe)机制,,,基于JDK1.8对Java中