2012-05-02 17 views
6

Estoy usando el PriorityBlockingQueue con un campo de prioridad. En mi prueba utilizo System#currentTime() para las prioridades; las mismas prioridades se obtienen cuando la computadora es tan rápida que los milisegundos son los mismos (o más como los milisegundos en una PC tienen un margen de error).¿Por qué un PriorityQueue no actuaría como una cola?

Cuando las prioridades son las mismas, la cola actúa como si fuera una pila, lo que parece extraño. ¿Existe una alternativa para que la cola actúe como si fuera una cola normal (es decir, FIFO en lugar de LIFO) cuando las prioridades de los elementos son las mismas?

Respuesta

11

Las operaciones en esta clase no garantizan el orden de los elementos con la misma prioridad. Si necesita imponer un pedido, puede definir clases o comparadores personalizados que utilicen una clave secundaria para romper relaciones en valores de prioridad primaria.

Los documentos PriorityBlockingQueuethemselves te dice esto, y cómo conseguir alrededor de él si es necesario.

+1

Vi los documentos, pero esperaba que ya hubiera una clase de utilidad para hacer una cola, no una pila. Si pongo la cola, debería ir a la parte posterior y saltar la cola si es una prioridad más alta. – Ben

+2

¿Por qué? La mayoría de los usuarios usan un 'PriorityBlockingQueue' _con diferentes prioridades._ –

+2

porque una Pila no es una Cola o es solo Semántica? – Ben

2

No creo que la cola de prioridad garantice el orden de obtener elementos iguales. Una opción es hacer que la prioridad sea más compleja: presione el valor negativo del tamaño de la cola cuando empuje el elemento junto con su prioridad y compare estos valores con elementos de igual prioridad.

1

Simplemente cree una PriorityBlockingQueue con su propio Comparador que tenga en cuenta el tiempo de creación (vea http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/PriorityBlockingQueue.html#PriorityBlockingQueue(int, java.util.Comparator)). Puede que tenga que cambiar sus claves de la Fecha simple a una clase de Fecha y contador, donde esta última se incrementará globalmente con cada creación (campo estático de su nueva clase de clave); no es realmente FIFO, sino más bien First Created First Out.

O simplemente implemente su propia clase PriorityQueueFifo.

0

Otra solución es mantener un contador en sus pruebas que utilice para la prioridad y que aumente en cada inserción. De esta manera, su cola de prioridad tendrá orden FIFO en sus pruebas, pero se verá como una cola de prioridad arbitraria.

Cuestiones relacionadas