[英]Use case for Future.cancel(false)?
在什么情况下,想要将mayInterruptIfRunning
参数的false
传递给Future.cancel()
?
如果我理解正确,如果您传递false
并且任务被取消但线程没有被中断,则结果(或ExecutionException
)将永远不可访问,因为任务仍被标记为已取消(即isCancelled()
返回true
并且get()
抛出CancellationException
。)
其他可能的情况是:
Runnable
或Callable
实现不检查中断,即使你中断它也会运行完成(这里中断没有区别) cancel()
之前,任务已经完成(再次中断没有区别) try ... finally
为此。) cancel
) 那么什么时候/为什么你会在不打断任务的情况下取消任务?
TL;博士; Future.cancel(false)
仅用于避免启动尚未启动的任务。
有关并发和取消的两个重要事项需要了解。
首先是在Java中取消纯粹是合作的。 Java通过阻塞方法抛出InterruptedExcetions并在Thread上设置一个标志来发出取消请求的信号。 任务实现负责注意取消请求并取消自身。 Brian Goetz解释了他在处理InterruptedException的帖子中的中断 。 并非所有任务实现都能正确处理中断。
要指出的第二件事是Future对象是一个占位符,用于将来要执行的任务的结果。 如果你没有很多线程在运行,那么任务可能会立即开始执行,但也可能是所有线程都已被使用而且任务必须等待。 仅仅因为您对Future对象的引用并不意味着相应的任务实际上已经开始运行。 这有点像预订。
您有一个Future对象,但该任务可能处于以下状态之一:
如果您的任务处于第一个状态“Waiting”,那么Future.cancel(true)
和Future.cancel(false)
都会将未来标记为已取消。 任务保留在要执行的任务队列中,但是当执行程序到达任务时,它会注意到已取消的标志并跳过它。
如果您的任务处于第三个状态“已完成”,则Future.cancel(true)
和Future.cancel(false)
返回false并且不执行任何操作。 这是有道理的,因为它们已经完成,并且没有办法撤消它们。
只有当您的任务处于第二个状态“正在运行”时, mayInterruptIfRunning
标志才有用。
如果您的任务正在运行且mayInterruptIfRunning
为false,则执行程序不会执行任何操作并允许任务完成。
如果您的任务正在运行并且mayInterruptIfRunning
为true,则执行程序将中断该任务。 但请记住关于合作取消的一点 - 为了中断工作,必须实施任务来处理取消。
摘要:
Future.cancel(true)
适用于:
Future.cancel(false)
是正确的:
我有一个可能对您感兴趣的用例:我有一个执行一组计划任务的线程。 其中一项任务可以由其自身或其他任务重新安排。
为此,我在队列中的现有副本上使用Future.cancel(false)
,然后为新时间安排任务。
如果从计划任务本身调用此代码,则取消操作将是无操作,并且该任务将被安排在将来再次运行。 如果从另一个上下文调用代码,则即将执行的任务尚未开始执行,因此它将被取消,并替换为为新时间安排的任务。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.