在ThreadPoolExecutor中清理有界队列

时间:2013-08-05 21:38:15

标签: java multithreading threadpoolexecutor

在阅读Threadpool执行器的文档时,我将在下面看到:

  

当大量排队的任务被取消时,有两个提供的方法remove(java.lang.Runnable)和purge()可用于协助存储回收。

我明白,如果任何任务被取消,我可以使用这些方法清理工作队列。 我试图了解实际来源中的哪个部分会自动清理 。 假设我从队列10开始,其中4个任务被取消,当新任务到达时,队列大小将为6或者它将忽略4个被取消的任务并重置为10。

从来源我看到这个评论:

/**
 * Tries to remove from the work queue all
 * 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.*
 */ 
 public void purge() { 

但有人可以告诉我工作线程在源中主动删除已取消任务的位置吗?

感谢您的时间,

1 个答案:

答案 0 :(得分:2)

当工作线程从ThreadPoolExecutor.getTask()中的工作队列中获取()任务并尝试运行()它们时,工作线程将在正常操作期间主动删除已取消的任务。当表示Runnable工作单元的底层FutureTask调用其FutureTask $ Sync.innerRun()时,它首先检查预期的READY状态 - 否则返回。因此,如果任务被取消,则会跳过执行,并且它已从workQueue中删除。如果任务已在运行,则FutureTask.cancel()的mayInterruptIfRunning标志将确定是否尝试执行interrupt()。

这意味着,默认情况下,取消的任务位于workQueue中,直到可用的Worker尝试处理它,发现任务被取消并完成其处理。因此,关于队列大小的问题的答案取决于工作人员是否已达到任何这些任务。 ThreadPoolExecutor.purge()允许您手动触发workQueue的立即遍历以删除已取消的任务。