繁体   English   中英

Future.cancel的用例(false)?

[英]Use case for Future.cancel(false)?

在什么情况下,想要将mayInterruptIfRunning参数的false传递给Future.cancel()

如果我理解正确,如果您传递false并且任务被取消但线程没有被中断,则结果(或ExecutionException )将永远不可访问,因为任务仍被标记为已取消(即isCancelled()返回true并且get()抛出CancellationException 。)

其他可能的情况是:

  • RunnableCallable实现不检查中断,即使你中断它也会运行完成(这里中断没有区别)
  • 在调用cancel()之前,任务已经完成(再次中断没有区别)
  • 任务需要在退出之前执行一些清理(一个编写良好的实现将使用try ... finally为此。)
  • 任务无法立即终止,必须继续执行受中断影响的操作,例如阻塞I / O(在这种情况下,您可能根本不应该cancel

那么什么时候/为什么你会在不打断任务的情况下取消任务?

TL;博士; Future.cancel(false)仅用于避免启动尚未启动的任务。

有关并发和取消的两个重要事项需要了解。

首先是在Java中取消纯粹是合作的。 Java通过阻塞方法抛出InterruptedExcetions并在Thread上设置一个标志来发出取消请求的信号。 任务实现负责注意取消请求并取消自身。 Brian Goetz解释了他在处理InterruptedException的帖子中的中断 并非所有任务实现都能正确处理中断。

要指出的第二件事是Future对象是一个占位符,用于将来要执行的任务的结果。 如果你没有很多线程在运行,那么任务可能会立即开始执行,但也可能是所有线程都已被使用而且任务必须等待。 仅仅因为您对Future对象的引用并不意味着相应的任务实际上已经开始运行。 这有点像预订。

您有一个Future对象,但该任务可能处于以下状态之一:

  1. 等候。 例如,它可能在等待处理器时间的其他任务的队列中。
  2. 运行。
  3. 已完成。

如果您的任务处于第一个状态“Waiting”,那么Future.cancel(true)Future.cancel(false)都会将未来标记为已取消。 任务保留在要执行的任务队列中,但是当执行程序到达任务时,它会注意到已取消的标志并跳过它。

如果您的任务处于第三个状态“已完成”,则Future.cancel(true)Future.cancel(false)返回false并且不执行任何操作。 这是有道理的,因为它们已经完成,并且没有办法撤消它们。

只有当您的任务处于第二个状态“正在运行”时, mayInterruptIfRunning标志才有用。

如果您的任务正在运行且mayInterruptIfRunning为false,则执行程序不会执行任何操作并允许任务完成。

如果您的任务正在运行并且mayInterruptIfRunning为true,则执行程序将中断该任务。 但请记住关于合作取消的一点 - 为了中断工作,必须实施任务来处理取消。

摘要:

Future.cancel(true)适用于:

  1. Future代表了一个长期运行的任务,已知它已经被实现来处理中断。

Future.cancel(false)是正确的:

  1. 任务实现无法处理被中断。
  2. 如果任务实现支持取消,它是未知的。
  3. 您愿意等待已经开始的任务完成。

如果您害怕中断任务的执行可能会使事情处于不良状态,并且您只是想将其标记为已取消,以便Future用户将意识到它(例如,他们应该知道请求的统计信息未执行时间)。

编写正确处理中断的线程代码根本不是微不足道的,因此人们可能更愿意避免它。

有些信息可以发现在这里在这里 ,当然在大书用Java并发编程 (由谁最初写的家伙java.util.concurrent )。

我有一个可能对您感兴趣的用例:我有一个执行一组计划任务的线程。 其中一项任务可以由其自身或其他任务重新安排。

为此,我在队列中的现有副本上使用Future.cancel(false) ,然后为新时间安排任务。

如果从计划任务本身调用此代码,则取消操作将是无操作,并且该任务将被安排在将来再次运行。 如果从另一个上下文调用代码,则即将执行的任务尚未开始执行,因此它将被取消,并替换为为新时间安排的任务。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM