用Java重新排序队列';s线程池执行器
可能重复:用Java重新排序队列';s线程池执行器,java,multithreading,Java,Multithreading,可能重复: 我有一个使用LinkedBlockingDequeue构建的ThreadPoolExecutor,我想操纵底层队列,但是在文档中阅读这个让我非常紧张 队列维护 方法getQueue()允许访问工作队列以进行监视和调试。强烈反对将此方法用于任何其他目的。提供的两个方法remove(java.lang.Runnable)和purge()可用于在取消大量排队的任务时帮助进行存储回收 具体来说,我希望能够 检查队列以查看元素是否已存在。我认为这很好,因为只查看队列中的元素不需要锁定 我想根
我有一个使用LinkedBlockingDequeue构建的ThreadPoolExecutor,我想操纵底层队列,但是在文档中阅读这个让我非常紧张 队列维护 方法getQueue()允许访问工作队列以进行监视和调试。强烈反对将此方法用于任何其他目的。提供的两个方法remove(java.lang.Runnable)和purge()可用于在取消大量排队的任务时帮助进行存储回收 具体来说,我希望能够
getQueue()
将始终返回传递到ThreadPoolExecutor
的确切阻塞队列
文档中的问题是,如果不能保证阻塞队列的线程安全,则很容易在双重运行时遇到问题。如果您使用PriorityBlockingQueue
,并且只使用remove
和add
(或者更直接地说,offer
),那么您将是安全的,您甚至可以直接从getQueue()
执行此操作
换句话说,每当您的信号告诉您某些Runnable
的优先级已更改时,您应该remove
它并检查移除的结果(true
如果移除),并且只有当它确实被移除时,您才应该重新添加它。您不能保证在这些操作之间不会拾取某些内容,但至少可以保证不会重复运行可运行的,如果使用包含->删除->添加
,这很容易发生
或者,您可以编写自己的阻塞队列
实现,该实现使用比较器
(如优先级阻塞队列
),在请求新数据时查找最高优先级。考虑到涉及的各种接口,这听起来需要做更多的工作。如文档所述,您不应该通过该方法控制队列。您应该从传递给ThreadPoolExecutor
的队列中控制它。但这是否仍然存在线程问题的风险?我想如果我调用getQueue()这与修改我传入的实际队列对象是一样的。我不认为我可以像另一个问题中建议的那样使用PriorityComparator,因为PriorityComparator无法在元素进入队列后对其进行重新排序。只要您删除,然后重新添加可运行的。