gpt4 book ai didi

java - Future.cancel(false) 的用例?

转载 作者:搜寻专家 更新时间:2023-10-30 19:56:01 25 4
gpt4 key购买 nike

在什么情况下需要将 false 参数的 mayInterruptIfRunning 传递给 <a href="http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/concurrent/Future.html#cancel%28boolean%29" rel="noreferrer noopener nofollow">Future.cancel()</a>

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

其他可能的情况是:

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

那么什么时候/为什么要在不中断任务的情况下取消它?

最佳答案

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

关于并发和取消,有两件重要的事情需要理解。

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

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

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

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

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

如果您的任务处于第三种状态“已完成”,那么 Future.cancel(true)Future.cancel(false) 都返回 false 并且不做任何事物。这是有道理的,因为它们已经完成并且没有办法撤消它们。

mayInterruptIfRunning 标志仅在您的任务处于第二状态“正在运行”时才重要。

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

如果您的任务正在运行并且 mayInterruptIfRunning 为真,则执行程序将中断任务。但请记住有关合作取消的一点 - 要使中断正常工作,必须实现任务来处理取消。

总结:

Future.cancel(true) 适用于:

  1. Future 代表一个长期运行的任务,已知已实现该任务以处理中断。

Future.cancel(false) 是正确的:

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

关于java - Future.cancel(false) 的用例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3271564/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com