2012-09-20 196 views
8

可能重复:
Java Executors: how can I set task priority?重新排序队列

我有一个ThreadPoolExecutor的使用LinkedBlockingDequeue建成,我想操纵底层的队列中,但是阅读本文档中,使我非常紧张。

队列维护

方法getQueue()允许访问工作队列用于监控和调试的目的。强烈建议不要将此方法用于任何其他目的。提供两个提供的方法remove(java.lang.Runnable)和purge()可用于在大量排队的任务被取消时协助存储回收。

具体我希望能够

  1. 检查队列,查看是否元素已经存在。我认为这很好,因为不需要锁定来查看队列中的元素。
  2. 我想根据某些信号对队列重新排序。这显然很麻烦。我想知道是否有一个首选的方法来做到这一点,这样我就不会搞乱其他用途的队列。

感谢

+0

正如文档注释,您不应该从该方法控制队列。你应该从传递给你的'ThreadPoolExecutor'的队列中控制它。 – pickypg

+0

但是,这样还是不能解决线程问题的风险?我想如果我调用getQueue(),就像修改我传入的实际队列对象一样。 – Jon

+2

我不认为我可以按照其他问题中的建议使用PriorityComparator,因为PriorityComparator在队列中没有提供对元素进行重新排序的方法。 – Jon

回答

4

getQueue()总是返回确切BlockingQueue<Runnable>您传递到ThreadPoolExecutor

文档的担忧是如果您不能保证BlockingQueue的线程安全性,您可能很容易遇到双重运行的问题。如果您使用PriorityBlockingQueue,并且只使用removeadd(或更直接地,offer),那么您将是安全的,并且您甚至可以直接从getQueue()执行此操作。

换句话说,只要你的信号告诉你一些Runnable的优先级已经改变,那么你应该remove并检查删除的结果(true如果删除),并且仅当它实际上是删除,那么你应该重新添加它。您不能保证在这些操作之间不会收到任何东西,但至少可以保证您不会双重运行Runnable,如果使用contains - >remove - >add,则很容易发生。

要么是这样,要么您可以编写自己的BlockingQueue实现,该实现使用Comparator(如PriorityBlockingQueue),每当要求输入新数据时都会找到最高优先级。鉴于涉及的各种接口,这听起来像是更多的工作。