java执行器服务。调用所有(超时,时间单位)与未来。获取(超时,时间单位)
我正在使用执行器服务。invokeAll(可调用、超时、时间单位)方法
在提交给ExecutorService的每个可调用服务中,我都有一个未来。get()
将成为未来。即使executorService已超时,get()仍将在后台运行
我是否必须指定未来的超时。获取(timeout,TimeUnit)并抛出一个TimeoutException,以确保未来被终止
你可以在下面搜索框中键入要查询的问题!
我正在使用执行器服务。invokeAll(可调用、超时、时间单位)方法
在提交给ExecutorService的每个可调用服务中,我都有一个未来。get()
将成为未来。即使executorService已超时,get()仍将在后台运行
我是否必须指定未来的超时。获取(timeout,TimeUnit)并抛出一个TimeoutException,以确保未来被终止
# 1 楼答案
正如the documentation所述:
它没有明确说明,但它使用
Future.cancel(true)
,即中断正在运行的任务。由于Future.get()
支持中断,这将导致它通过抛出InterruptedException
来完成。如果Callable
没有捕捉到它,也没有执行任何可能重置中断状态的操作,这意味着如果指定给invokeAll
的超时时间已过,可调用项将停止在Future.get()
中等待然而,
invokeAll
只取消未来,因此,发送中断信号,但不等待线程对其做出反应并完成Callable
代码的执行。因此,当invokeAll
由于超时而完成时,一些线程可能仍然在已经取消的任务上运行。但是,如果这些任务仅仅由future::get
组成,那么这就不应该是一个问题但是,如果您只想等待现有
Future
列表的完成,那么您可以更高效地完成这项工作。毕竟,您正在将每个Future
包装成一个调用Future.get
的Callable
,该invokeAll
将包装成另一个Future
,可能会在每个未来阻塞一个工作线程,然后等待所有这些未来的完成。最后一步正是这项任务的目的,所以你可以不用前面的步骤来完成它,例如:这基本上就是
AbstractExecutorService
在提交了所有Callable
之后等待所有期货完成的方式,为每个期货创建一个Future
。如前所述,如果你想做的只是等待现有未来的列表,你可以直接这样做,而不需要通过向执行者提交作业来浪费资源。使用这种方法的另一个好处是,这将取消原始的期货,而不仅仅是取消等待期货的工作。您还可以依赖此方法中断取消,而此属性不是为invokeAll
显式指定的# 2 楼答案
来自Javadoc
所以1。所有结果都将由所有
Callable
提供,包括内部future.get()
调用的结果,以及2。一旦invokeAll返回(即在超时之前),所有期货都将终止