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

如何并行运行boolean类型的CompletableFutures,并在所有任务返回TRUE时在第一个假结果或返回时退出?

商宏爽
2023-03-14

所以我有一个用例,我有四个任务a,B,C,D,我想并行运行。这些任务的响应类型是布尔型的。

在并行运行它们之后,我想在以下任一条件下停止执行

  1. 从任一任务接收第一个false时返回。
  2. 4个任务全部完成,没有一个返回false。

我的项目使用的是Java,springboot

所以我试图使用可完成的未来来实现这一点。我可以在第一步成功,就像下面的代码一样。但不是第二步。有什么帮助吗?

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.function.Consumer;
import java.util.function.Predicate;


public class CompFutu {
    public static <T> CompletableFuture<T> firstMatchingCondition(
            List<? extends CompletionStage<? extends T>> work,
            Predicate<? super T> successFullResultCondition) {

        CompletableFuture<T> result = new CompletableFuture<>();

        Consumer<T> tester = workUnit -> {
            if (successFullResultCondition.test(workUnit)) {
                result.complete(workUnit);
            }
        };

        work.forEach(s -> s.thenAccept(tester));
        return result;
    }

    public static void main(String[] args) throws Exception {

        List<CompletableFuture<Boolean>> list= Arrays.asList(
                CompletableFuture.supplyAsync(()-> {
                    try {
                        System.err.println(Thread.currentThread().getName());
                        Thread.sleep(1000);
                        System.err.println("DONE(true 1) "+Thread.currentThread().getName());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return true;
                }),
                CompletableFuture.supplyAsync(()-> {
                    try {
                        System.err.println(Thread.currentThread().getName());
                        Thread.sleep(20_000);
                        System.err.println("DONE(false 20) "+Thread.currentThread().getName());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return false;
                }),
                CompletableFuture.supplyAsync(()-> {
                    try {
                        System.err.println(Thread.currentThread().getName());
                        Thread.sleep(5000);
                        System.err.println("DONE(false 5) "+Thread.currentThread().getName());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return false;
                })
        );

        firstMatchingCondition(list, i->!i).join();

        System.err.println("Done");

    }
}

共有1个答案

梁丘烨
2023-03-14

创造另一个未来,当所有的未来都完成时,它将被完成,除了你的未来,一旦你满足了条件,它将被完成。然后,将它们结合到一个未来中,一旦其中一个完成,这个未来就会完成:

CompletableFuture<?> firstFalse = firstMatchingCondition(list, i -> !i);
CompletableFuture<?> all
    = CompletableFuture.allOf(list.toArray(new CompletableFuture<?>[0]));

CompletableFuture.anyOf(firstFalse, all).join();

您可以将创建内联到单个表达式中。

CompletableFuture.anyOf(
    firstMatchingCondition(list, i -> !i),
    CompletableFuture.allOf(list.toArray(new CompletableFuture<?>[0]))
).join();

但重要的是要记住,这只会影响启动线程在继续之前等待的时间。这不会取消其他未来,而且由于CompletableFuture通常不支持中断,因此无法停止正在进行的评估。只有他们的结果会被忽略。

 类似资料:
  • 我的数据库中有两个表: 表1:购买物品 表1列出了购买的物品,表2每小时更新一次每件物品的当前价格。因此,从表2中可以清楚地看出,肉类最后一次交易是在2013年2月20日上午10点,而鱼类不是在同一天交易的,它是在2013年2月19日上午9点交易的,鸡肉是在2013年2月20日上午9点交易的。我想做的是,列出表1中的所有项目,并加入表2中各个项目的最后交易价格,如下所示: 这里应该应用什么类型的连

  • 问题内容: 我有一张桌子,里面有人和他们拥有的汽车 该查询为我提供了和拥有完全相同的汽车以及Lisa本人的人,这很好。 结果: 如果我想查找所有拥有相同汽车的人,请重新运行查询,结果应为我。 现在,我有一个Java名称列表,对于每个名称,我都运行此查询。真的很慢。无论如何,是否可以找到所有拥有相同汽车的人,并在单个数据库调用中将结果划分为组? 例如,使用第一个表。我可以运行将名称分组的查询。请注意

  • 我对promise不熟悉。我查找了按顺序执行promise的示例,但没有找到与我的应用程序类似的示例。 我的问题是,我想按照一定的顺序解决promise,但也要捕获promise解决时的所有结果。通过查找例子。我已经创建了这个问题的简化版本。 我能够创建一个函数doWork(),但问题是它所做的只是按顺序解决promise,而没有捕获结果。 理想情况下,我想要一个返回promise的函数,该函数将

  • 我有一点奇怪的情况,似乎不允许这个挂钩适合任何广泛建立的CompletableFuture漏洞。 在评估返回布尔值的主要方法中,我希望允许对三个不同方法的调用异步完成。这三个方法中的每一个都可以返回TRUE或FALSE。 如果任何返回FALSE,我希望评估删除余数并简单地返回FALSE值。重点是,它可以是三个中的任何一个,不一定是第一个。 但最重要的是,我需要在实际返回TRUE之前等待所有三个返回

  • 我必须并行运行多个期货,程序不应该崩溃或挂起。 目前,我一个接一个地等待期货,如果存在TimeoutException,则使用回退值。 如我所见,这个代码片段的最大等待时间是< code > time out 1 time out 2 time out 3 我的问题是:我怎么能同时等待所有这些期货,这样我就可以将等待时间减少到? 编辑:最后我用了@Jatin和@senia的修改答案: 后来它使用如

  • 我在mongoDB中使用聚合方法进行分组,但当我使用时,它返回我用于分组的唯一字段。我试过,但它也不起作用。我还尝试了,它成功了,但结果数据现在的格式不同了。 我需要的响应格式如下: 在我的查询中添加$group之后。响应是这样的,_id的值会发生变化。(而且$group只接受_id,如果我尝试任何其他关键字,它会抛出一个累加器错误。请解释一下。) 我必须删除名称字段中的重复项,而不改变任何结构和