【问题标题】:Why would a PriorityQueue not act like a Queue?为什么 PriorityQueue 不像队列那样工作?
【发布时间】:2012-05-12 01:04:32
【问题描述】:

我正在使用带有优先级字段的PriorityBlockingQueue。在我的测试中,我使用System#currentTime() 来表示优先级——相同的优先级是由计算机获得的速度如此之快以至于毫秒是相同的(或者更像是 PC 上的毫秒有误差范围)。

当优先级相同时,队列就像一个堆栈,这看起来很奇怪。当元素的优先级相同时,是否有其他方法可以让队列像普通队列一样工作(即 FIFO 而不是 LIFO 行为)?

【问题讨论】:

    标签: java stack queue priority-queue


    【解决方案1】:

    对此类的操作不保证具有相同优先级的元素的顺序。如果您需要强制执行排序,您可以定义自定义类或比较器,它们使用辅助键来打破主要优先级值的关系。

    PriorityBlockingQueue 文档 themselves 会告诉您这一点,以及如何在需要时解决它。

    【讨论】:

    • 看过文档,但预计已经有一个实用程序类用于制作队列而不是堆栈。如果我加入队列,如果它的优先级更高,它应该退到后面并跳过队列。
    • 为什么?大多数用户使用PriorityBlockingQueue具有不同的优先级。
    • “不保证具有相同优先级的元素的顺序。”这意味着它可以像一个堆栈,它可以像一个队列,它可以完全随机地运行,它可能取决于是星期二还是外面是否阳光充足。 没有保证。
    • 对不起,我的问题措辞不正确,我正在寻找一种替代方案,以保证优先级相等时的顺序(即始终为队列)。就像与 google 或 apache 不同的实用程序(如果有的话),并且不需要创建具有原子长序列号的 FIFO 类。
    • 不,别无选择。不过,您可以围绕 PriorityBlockingQueue 编写一个包装器,在内部执行 AtomicLong 的内容。
    【解决方案2】:

    我认为优先队列不能保证获得相等元素的顺序。一种选择是使优先级更复杂 - 在推送元素及其优先级时推送队列大小的负数,并比较这些值以获得相同优先级的元素。

    【讨论】:

      【解决方案3】:

      只需使用您自己的 Comparator 创建一个 PriorityBlockingQueue,它会考虑创建时间(请参阅 http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/PriorityBlockingQueue.html#PriorityBlockingQueue(int, java.util.Comparator) )。 您可能必须将键从简单的 Date 更改为 Date 和 counter 的类,后者将随着每次创建而全局递增(新键类的静态字段);它不是真正的先进先出,而是先创建先出。

      或者,只需实现您自己的 PriorityQueueFifo 类。

      【讨论】:

        【解决方案4】:

        另一种解决方案是在您的测试中维护一个计数器,用于确定优先级,并在每次插入时增加该计数器。这样,您的优先级队列将在您的测试中具有 FIFO 排序,但它看起来像一个任意优先级队列。

        【讨论】:

          猜你喜欢
          • 2018-01-11
          • 1970-01-01
          • 2011-05-13
          • 2011-06-08
          • 1970-01-01
          • 2016-04-23
          • 2016-05-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多