cancel() vs remove() 在执行者上

cancel() vs remove() on executors

最近我使用了 ThreadPoolExecutor 和 priorityqueue,并在未来的任务中遇到了这两种方法 future.cancel()。 并且 task.remove() 在它自己的任务上,将其从队列中删除。

更好的选择是什么?有什么不同吗?我可以保存两者的列表(从 submit() 接收到的未来对象或任务本身),不确定要使用什么...

删除:

executor.remove(task);
executor.purge();

取消:

futureObject.cancel(false);

我使用了以下内容: http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html#remove%28java.lang.Runnable%29

cancel中的false是因为我只想移除一个队列任务,如果它运行,让它完成。

我会用对你来说更自然的那种。没有进一步的信息,很可能是 cancel

remove/purge 成本高得多,只有在您担心会有太多这样的任务时才真正需要它们,它们可能会占用太多内存。

区别很明显,取消只是取消任务。 remove/purge 从队列中删除任务。

如果您希望 cancel 被覆盖,或者您主要关心的是内存占用,则使用 remove/purge。但在任何其他情况下,我会选择 cancel

使用Future.cancel()

ThreadPoolExecutor.remove() 的 Javadoc 声明它可能 "fail to remove tasks that have been converted into other forms before being placed on the internal queue",所以我不建议调用它,除非您确定任务没有在内部转换。

鉴于此,如果您有一个 Future,我建议您通过调用 Future.cancel() 来取消它。如果其他人引用了 Future 并决定调用 Future.get()

,那么这样做的另一个好处是可以做正确的事情

如果你对被取消的任务使用的堆的数量有疑虑,你可以在调用Future.cancel()后调用ThreadPoolExecutor.purge()

顺便说一下,ThreadPoolExecutor.purge() 方法只会删除已取消的 Future,因此在 remove() 之后调用 purge() 可能是空操作。