简体   繁体   English

如何使用 CompletableFuture 的 supplyAsync 每次运行具有多个输入的相同方法?

[英]How to use supplyAsync of CompletableFuture to run the same method with multiple inputs each time?

I have the following code where I create a supplier and use the completableFuture's supplyAsync method to invoke another method after async execution.我有以下代码,在其中创建供应商并使用 completableFuture 的 supplyAsync 方法在异步执行后调用另一个方法。

public void runParallelFunctions(MyInput myInput) {
    Supplier<Map<String, String>> taskSupplier = () -> {
        try {
            return invokeLambda("input1");
        } catch (Exception e) {
            System.out.println(e);
        }
        return new HashMap<>();
    };
    
    for (int i = 0; i < 5; i++) {
        CompletableFuture.supplyAsync(taskSupplier::get, executorService)
                         .thenAccept(this::printResultsFromParallelInvocations);
    }
    System.out.println("Doing other work....");
}

Below is the method I call after the execution completes.下面是我在执行完成后调用的方法。

private void printResultsFromParallelInvocations(Map<String, String> result) {
        result.forEach((key, value) -> System.out.println(key + ": " + value));
}

In the above code, how can I call the method invokeLambda passing multiple arguments like "input1", "input2" etc.?在上面的代码中,如何调用方法invokeLambda传递多个 arguments,如“input1”、“input2”等? I can generate the inputs through a loop, but how can I use some sort of a list with the supplier so that I can call the entire list for supplyAsync method?我可以通过循环生成输入,但是如何与供应商一起使用某种列表,以便我可以为 supplyAsync 方法调用整个列表? I cannot use runAsync method because I have a return value that I need to call printResultsFromParallelInvocations with.我不能使用 runAsync 方法,因为我有一个需要调用printResultsFromParallelInvocations的返回值。 I'm new to futures and async callbacks and would appreciate any help.我是期货和异步回调的新手,不胜感激。 Thanks in advance.提前致谢。

You can not create a single Supplier<Map<String, String>> and expect it to behave differently for the five evaluations.您不能创建单个Supplier<Map<String, String>>并期望它在五次评估中表现不同。 It would require external mutable state to make it detectable that an evaluation is the n'th evaluation which at the same time contradicts the idea of performing five concurrent evaluations which have no order.它将需要外部可变 state 才能检测到评估是第 n 个评估,这同时与执行五个没有顺序的并发评估的想法相矛盾。

Simply create five different suppliers, eg只需创建五个不同的供应商,例如

for(int i = 0; i < 5; i++) {
    String input = "input" + i;
    CompletableFuture.supplyAsync(() -> invokeLambda(input), executorService)
        .thenAccept(this::printResultsFromParallelInvocations);
}

In each loop iteration, the lambda expression () -> invokeLambda(input) captures the current value of input and creates an appropriate Supplier instance.在每次循环迭代中,lambda 表达式() -> invokeLambda(input)捕获input的当前值并创建适当的Supplier实例。

Side notes:旁注:

  • Don't name methods after technical aspects like invokeLambda but rather try to express their purpose .不要以像invokeLambda这样的技术方面来命名方法,而是尝试表达它们的目的

  • the taskSupplier::get in your original code was an unnecessary method reference as it produced a Supplier invoking the method on an object that was already a Supplier .原始代码中的taskSupplier::get是不必要的方法引用,因为它产生了一个Supplier调用 object 上已经是Supplier的方法。 So taskSupplier could have been passed to supplyAsync directly if getting the same behavior for every evaluation was intended.因此,如果想要为每个评估获得相同的行为, taskSupplier可以直接传递给supplyAsync

You can create new Supplier on the fly inside the loop.您可以在循环内动态创建新的供应商。

public static Supplier<Map<String, String>> supplierFunc(Object... args) {
    return () -> {
        try {
            return invokeLambda(args);
        } catch (Exception e) {
            System.out.println(e);
        }
        return new HashMap<>();
    };
}

public void runParallelFunctions(Object myInput) {
    for (int i = 0; i < 5; i++) {
        CompletableFuture.supplyAsync(supplierFunc("input1", "input2"), executorService)
                .thenAccept(this::printResultsFromParallelInvocations);
    }
    System.out.println("Doing other work....");
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将CompletableFuture.supplyAsync与PriorityBlockingQueue一起使用? - How do I use CompletableFuture.supplyAsync together with PriorityBlockingQueue? 如何为CompletableFuture :: supplyAsync选择Executor - How to chose an Executor for CompletableFuture::supplyAsync CompletableFuture supplyAsync - CompletableFuture supplyAsync TheApplyAsync with CompletableFuture 使用与 SupplyAsync 线程相同的线程 - TheApplyAsync with CompletableFuture uses the same thread as SupplyAsync thread 使用CompletableFuture.supplyAsync返回多个值 - Returning multiple values with CompletableFuture.supplyAsync 如何在CompletableFuture.supplyAsync(Supplier <U>供应商)方法中使用所需数量的工作线程设置ForkJoinPool? - How to set ForkJoinPool with the desired number of worker threads in CompletableFuture.supplyAsync(Supplier<U> supplier) method? Java 8 CompletableFuture-如何在同一输入上运行多个功能 - Java 8 CompletableFuture - how to run multiple functions on same input 当同一个被调用两次时,CompletableFuture 的“SupplyAsync”部分会发生什么 - What happens to the “SupplyAsync” portion of CompletableFuture when same one is called twice JDK8 CompletableFuture.supplyAsync 如何处理interruptedException - JDK8 CompletableFuture.supplyAsync how to deal with interruptedException 如何将completableFuture.supplyAsync()的返回类型分配给对象? - how to assign the return type of completableFuture.supplyAsync() to the object?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM