java - ExecutorService.submit() 与 ExecutorSerivce.invokeXyz()
问题描述
ExecutorService
包含以下方法:
invokeAll(Collection<? extends Callable<T>> tasks)
invokeAny(Collection<? extends Callable<T>> tasks)
submit(Callable<T> task)
我对使用 termssubmit
和invoke
. 这是否意味着invokeXyz()
方法通过底层线程池尽快调用这些任务并对submit()
提交的任务进行某种调度。
这个答案说“如果我们想等待所有已提交给 ExecutorService 的任务完成”。这里的“等待”指的是什么?
解决方案
两者都invoke..()
将submit()
立即执行它们的任务(假设线程可用于运行任务)。不同之处在于invoke...()
它将等待在不同线程中运行的任务完成后再返回结果,而submit()
将立即返回,这意味着它执行的任务仍在另一个线程中运行。
换句话说,从Future
返回的对象invokeAll()
保证处于Future.isDone() == true
. 从返回的Future
对象submit()
可以处于Future.isDone() == false
.
我们可以很容易地证明时间差异。
public static void main(String... args) throws InterruptedException {
Callable<String> c1 = () -> { System.out.println("Hello "); return "Hello "; };
Callable<String> c2 = () -> { System.out.println("World!"); return "World!"; };
List<Callable<String>> callables = List.of(c1, c2);
ExecutorService executor = Executors.newSingleThreadExecutor();
System.out.println("Begin invokeAll...");
List<Future<String>> allFutures = executor.invokeAll(callables);
System.out.println("End invokeAll.\n");
System.out.println("Begin submit...");
List<Future<String>> submittedFutures = callables.stream().map(executor::submit).collect(toList());
System.out.println("End submit.");
}
结果是在方法完成之前callables
打印他们的 Hello World 消息;但方法完成后打印 Hello World 。invokeAll()
callables
submit()
/*
Begin invokeAll...
Hello
World!
End invokeAll.
Begin submit...
End submit.
Hello
World!
*/
您可以在 IDE 中使用此代码,方法是在或中添加一些sleep()
时间并观察终端打印出来的情况。这应该使您确信确实在等待某事发生,但没有。c1
c2
invoke...()
submit()
推荐阅读
- javascript - Woocommerce 结帐 scroll_to_notices
- javascript - apollo react hooks中fetchMore函数的updateQuery似乎没有做任何事情
- parallel-processing - 使用 OpenMP 缩减时的精度损失
- java - java中带有3个验证参数的输入验证
- reactjs - GLTF 文件部分加载为黑色 ThreeJS、React、Typescript、如何为所有 3D 对象添加颜色/灯光
- pandas - 使用 .get_file() 将自定义数据加载到 TensorFlow
- regex - 如何解决 AppleScript 中的这些 grep 错误?
- linux - 如何在不登录的情况下知道公开可用的 ntp 池服务器上的当前时间?
- c# - 从未显示最后一个值的滑块值更改事件触发任务
- powershell - 如何排除 Pester 配置中的路径?