java - 链 CompletableFuture 并在第一次成功时停止
问题描述
我正在使用一个返回CompletableFuture
s 来查询设备的 API(类似于digitalpetri modbus)。
我需要用几个选项调用这个 API 来查询设备并弄清楚它是什么——这基本上是反复试验,直到它成功。这些是我无法更改的嵌入式设备协议,但您可以认为该过程类似于以下内容:
- 你是苹果吗?
- 如果不是,那你是菠萝吗?
- 如果不是,那你是钢笔吗?
- ...
虽然 API 使用期货,但实际上,通信是串行的(通过同一条物理线路),因此它们永远不会同步执行。一旦我知道它是什么,我希望能够停止尝试并让调用者知道它是什么。
我已经知道我只能得到一个期货的结果any
(见下文),但这可能会导致应该避免的额外尝试。
有没有一种模式来链接期货,一旦其中一个成功就停止?
类似,但浪费了非常有限的资源。
List<CompletableFuture<String>> futures = Arrays.asList(
CompletableFuture.supplyAsync(() -> "attempt 1"),
CompletableFuture.supplyAsync(() -> "attempt 2"),
CompletableFuture.supplyAsync(() -> "attempt 3"));
CompletableFuture<String>[] futuresArray = (CompletableFuture<String>[]) futures.toArray();
CompletableFuture<Object> c = CompletableFuture.anyOf(futuresArray);
解决方案
我认为你能做的最好的事情是,在你检索到结果之后,
futures.forEach(f -> f.cancel(true));
这不会影响产生结果的一方,并尽力阻止其他一方。由于 IIUC 是从外部来源获得的,因此不能保证它实际上会中断他们的工作。
然而,由于
此类无法直接控制导致其完成的计算,取消被视为另一种形式的异常完成
(来自CompletableFuture
文档),我怀疑它会做你真正想要的。
推荐阅读
- android - 带有 AsyncLayoutInflater 的 Android 片段 onCreateView
- javascript - 如何根据屏幕宽度动态设置道具?
- python - 在 Pandas 中按月根据环比值更新一列
- python-3.x - 如何使用flask-sqlalchemy的ORM DB API来使用json_extract、json_each、json_tree等sqlite json1特性?
- for-loop - Shopify 主题开发 - 创建新闻页面,其中“新闻”是博客“类别”
- .net - 从多个帐户获取日历约会
- java - 如何使用 2 组 RadioButton 在 EditText 中输入文本
- python - 迭代整数以获得随机种子是否合适?
- powershell - 在 Jenkins 管道中读取属性并将变量传递给 Powershell
- ruby-on-rails - 轮播图片源不会链接到图片,图片不会显示在网页上