2012-05-02 4 views
6

Я использую PriorityBlockingQueue с полем приоритета. В своем тестировании я использую System#currentTime() для приоритетов - одни и те же приоритеты получаются с таким быстродействующим компьютером, что миллисекунды одинаковы (или больше похоже на миллисекунды на ПК с погрешностью).Почему PriorityQueue не будет действовать как очередь?

Когда приоритеты одинаковы, очередь действует так, как если бы это был стек, который кажется странным. Есть ли альтернатива для того, чтобы очередь выполнялась так, как если бы она была нормальной (то есть FIFO, а не LIFO-поведением), когда приоритеты элементов одинаковы?

ответ

11

Операции в этом классе не дают гарантий относительно порядка элементов с одинаковым приоритетом. Если вам нужно обеспечить соблюдение порядка, вы можете определить пользовательские классы или компараторы, которые используют вторичный ключ для разрыва связей в значениях первичного приоритета.

The PriorityBlockingQueue документы themselves сказать вам это, и как получить вокруг него, если вам нужно.

+1

Видел документы, но ожидал, что уже будет класс утилиты для создания очереди, а не стека. Если я ставлю очередь, она должна перейти в обратную сторону и перепрыгнуть в очередь, если ее более высокий приоритет. – Ben

+2

Почему? Большинство пользователей используют «PriorityBlockingQueue» с разными приоритетами. –

+2

потому что стек не является очередью или это просто семантика? – Ben

2

Я не думаю, что очередь приоритетов гарантирует порядок получения равных элементов. Один из вариантов заключается в том, чтобы приоритет был более сложным - нажимайте отрицательный размер очереди при нажатии элемента вместе с его приоритетом и сравнивайте эти значения для элементов с равным приоритетом.

1

Просто создайте PriorityBlockingQueue со своим собственным компаратором, который учитывает время создания (см. http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/PriorityBlockingQueue.html#PriorityBlockingQueue(int, java.util.Comparator)). Возможно, вам придется сменить свои ключи от простой даты до класса Date и счетчика, где последний получит глобальное увеличение с каждым созданием (статическое поле вашего нового ключевого класса); это не FIFO, а First First First Out.

Или просто реализуйте свой собственный класс PriorityQueueFifo.

0

Другим решением является поддержание счетчика в ваших тестах, которое вы используете для приоритета, и которое вы увеличиваете при каждой вставке. Таким образом, ваша очередь приоритетов будет иметь порядок FIFO в ваших тестах, но она будет выглядеть как очередная очередь приоритетов.