[英]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.