tl;博士; 仅用于避免启动尚未启动的任务。Future.cancel(false)
关于并发性和取消,有两件重要的事情需要了解。
首先,在Java中,取消是纯粹的合作。Java 通过让阻塞方法抛出 InterruptedExcetions 并在 Thread 上设置标志来发出取消请求的信号。任务实现负责注意到取消请求并取消自身。Brian Goetz在他的帖子《Dealing with InterruptedException》中解释了中断。并非所有任务实现都能正确处理中断。
需要指出的第二件事是,Future 对象是将来要执行的任务的结果的占位符。如果您没有运行很多线程,则任务可能会立即开始执行,但也有可能所有线程都已被使用,任务必须等待。仅仅因为您有对 Future 对象的引用,并不意味着相应的任务实际上已开始运行。它有点像预订。
您有一个 Future 对象,但任务可能处于以下状态之一:
- 等待。例如,它可能位于等待处理器时间的其他任务的队列中。
- 运行。
- 完成。
如果您的任务处于第一个状态“正在等待”,则两者都将和将未来标记为已取消。任务保留在要执行的任务队列中,但当执行程序到达任务时,它会注意到已取消的标志并跳过它。Future.cancel(true)
Future.cancel(false)
如果你的任务处于第三种状态“已完成”,则两者都返回 false 并且不执行任何操作。这是有道理的,因为它们已经完成了,没有办法撤消它们。Future.cancel(true)
Future.cancel(false)
仅当任务处于第二种状态“正在运行”时,该标志才重要。mayInterruptIfRunning
如果您的任务正在运行并且是假的,则执行程序不会执行任何操作并允许任务完成。mayInterruptIfRunning
如果您的任务正在运行且为 true,则执行程序将中断该任务。但请记住关于合作取消的一点 - 对于工作中断,必须实施任务来处理取消。mayInterruptIfRunning
总结:
Future.cancel(true)
适用于以下情况:
- “未来”表示一个长期运行的任务,已知已实现该任务以处理中断。
Future.cancel(false)
将是正确的:
- 任务实现无法处理中断。
- 任务实现是否支持取消是未知的。
- 您愿意等待已经开始的任务完成。