`Future.cancel(true)`会将任务从队列中移除吗?

huangapple go评论76阅读模式
英文:

Does Future.cancel(true) remove the task from the queue?

问题

我对 Future.cancel(true) 的行为有点困惑。如果任务已经在运行,它会 interrupt 该任务,但那些尚未启动的任务呢?它们会被取消吗?它们会从队列中移除吗?在 Stackoverflow 上,我找到了一些相互矛盾的答案:

不会从队列中移除任务

会从队列中移除任务

有人可以解释一下实际的行为吗?

英文:

I am a little confused on the behavior of Future.cancel(true). It does interrupt the task if it is already running but what about the ones that have not yet started? They do get cancelled but are they removed from the queue or not? In Stackoverflow I found contradcting answers:

Does not remove the task from the queue

Does remove the task from the queue

Can someone explain the actual behavior?

答案1

得分: 4

在使用常用的ThreadPoolExecutor表示作业的情况下,被取消的任务不会立即从队列中移除,正如方法purge()所指示的:

> #### purge()
> 尝试从工作队列中移除所有已被取消的Future任务。该方法可以作为存储回收操作,对功能没有其他影响。被取消的任务永远不会被执行,但可能会在工作队列中累积,直到工作线程能够主动将它们移除。调用此方法会尝试立即移除它们。然而,在其他线程干扰的情况下,该方法可能无法移除任务。

CompletableFuture的情况下,虽然没有明确说明,但由于CompletableFutureExecutor抽象上操作,对实现没有任何控制,我们可以假设它不会从任何队列中移除已取消的作业。但如果在取消时未满足先决条件(例如,在使用asyncJob.thenApplyAsy(…, someExecutor)并在asyncJob完成之前取消它),该作业可能一开始就不会被加入队列。

英文:

In case of futures representing jobs of the commonly used ThreadPoolExecutor, cancelled tasks are not immediately removed from the queue, as the method purge() indicates:

> #### purge()
> Tries to remove from the work queue all Future
tasks that have been cancelled. This method can be useful as a
storage reclamation operation, that has no other impact on
functionality. Cancelled tasks are never executed, but may
accumulate in work queues until worker threads can actively
remove them. Invoking this method instead tries to remove them now.
However, this method may fail to remove tasks in
the presence of interference by other threads.

In case of CompletableFuture, it’s not said explicitly, but since the CompletableFuture operates on the Executor abstraction and has no control over the implementation at all, we can assume that it won’t remove cancelled jobs from any queue. But if the prerequisites were not fulfilled at the point of cancellation (i.e. when you use asyncJob.thenApplyAsy(…, someExecutor) and cancel it before asyncJob has been completed), the job might not get enqueued in the first place.

答案2

得分: 1

唯一可靠的信息来源是官方文档,也就是 Future#cancel 的描述。它表示实现应该尝试从队列中移除任务,但并没有义务这样做。由于 Future 是一个接口,我们可能期望不同的实现行为有所不同。

英文:

The only reliable source of information is official documentation, that is, Future#cancel description. It says implementation should try to remove the task from the queue, but is not obliged to do so. Since the Future is an interface, we may expect different implementations to behave differently.

huangapple
  • 本文由 发表于 2020年10月18日 23:20:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/64414985.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定