2012-09-20 20 views
8

Duplicar posibles:
Java Executors: how can I set task priority?cola Reordenar en ThreadPoolExecutor de Java

Tengo un ThreadPoolExecutor construido utilizando un LinkedBlockingDequeue y quiero manipular la cola subyacente, sin embargo leyendo esto en la documentación que hace estoy muy nervioso.

mantenimiento cola

Método getQueue() permite el acceso a la cola de trabajo para fines de monitoreo y depuración. El uso de este método para cualquier otro propósito es altamente desaconsejado. Dos métodos suministrados, eliminar (java.lang.Runnable) y purgar() están disponibles para ayudar en la recuperación de almacenamiento cuando se cancela un gran número de tareas en cola.

Específicamente quiero ser capaz de

  1. comprobar la cola para ver si un elemento ya existe. Supongo que esto está bien ya que no debería ser necesario bloquear solo para ver los elementos en la cola.
  2. Quiero reordenar la cola en función de alguna señal. Esto obviamente puede ser problemático. Me preguntaba si hay una forma preferida de hacerlo para no estropear la cola para otros usos.

Gracias

+0

Como indica la documentación, no debe controlar la cola desde ese método. Deberías controlarlo desde la cola que pasaste a tu 'ThreadPoolExecutor'. – pickypg

+0

¿Pero todavía no corre el riesgo de problemas? Pensé que si llamaba a getQueue() eso es lo mismo que modificar el objeto de cola real que paso. – Jon

+2

No creo que pueda usar un PriorityComparator como se sugiere en la otra pregunta porque PriorityComparator no proporciona ninguna forma de reordenar los elementos una vez que están en la cola. – Jon

Respuesta

4

getQueue() siempre devolverá la exacta BlockingQueue<Runnable> que se pasa en el ThreadPoolExecutor.

La preocupación con la documentación es que fácilmente podría tener problemas con el doble funcionamiento si no puede garantizar la seguridad del hilo del BlockingQueue. Si usa un PriorityBlockingQueue, y solo usa remove y add (o, más directamente, offer), entonces estará seguro, e incluso puede hacerlo directamente desde el getQueue().

En otras palabras, cada vez que la señal le indica que la prioridad alguna Runnable 's ha cambiado, entonces usted debe remove y comprobar el resultado de la eliminación (true si se retira), y sólo si se quitan realmente, entonces debería volver a agregarlo. No está garantizado que algo no se recoja entre esas operaciones, pero al menos está garantizado que no ejecutará el Runnable, lo que podría suceder fácilmente si se hace con contains ->remove ->add.

O eso, o puede escribir su propia implementación de un BlockingQueue que utiliza un Comparator (como el PriorityBlockingQueue) que encuentra la más alta prioridad siempre que se le preguntó por los nuevos datos. Esto parece mucho más trabajo dado las diversas interfaces involucradas.

Cuestiones relacionadas