¿Cuál sería un uso real de DelayQueue , qué problema común fue diseñado para resolver?
fuente
¿Cuál sería un uso real de DelayQueue , qué problema común fue diseñado para resolver?
Recientemente utilicé una cola de retraso para limitar la velocidad.
Para un límite de X eventos por segundo, coloque cada evento en una cola de retraso con un retraso de 1 segundo.
Si hay X eventos en el delayQueue, tome () de la cola (que bloquea hasta que al menos 1 expire). De esta forma, permite una explosión a corto plazo, sin exceder los límites a largo plazo.
Esta clase es perfecta para un hilo que quiere procesar múltiples eventos retrasados en su orden correcto.
Supongamos, por ejemplo, que tiene una pantalla con 100 luces intermitentes, y todas las luces parpadean a diferentes velocidades no relacionadas. Podría tener un hilo para cada luz, o podría hacer que un hilo las coordine todas utilizando esta clase. Funcionaría algo como esto:
Light
clase con una tasa de flashDelayed
interfaz que apunte a la luz, digamosLightFlash
DelayQueue
y agregue uno nuevo LightFlash
para cada luz, con la demora adecuada para la velocidad de destello de la luzDelayQueue se encarga de procesar el próximo evento.
Se me ocurren dos ejemplos del mundo real:
DelayQueue
probablemente se implementa como una cola prioritaria , que generalmente se implementa mejor como un montón .
el uso principal sería temporizadores de tareas como para las clases Timer
si uno pudiera hacer que la demora sea independiente del reloj del sistema (lo cual creo que puede, aunque no estoy seguro), puede usarlo para eventos de juegos como "después de que 5 ticks se muevan a X" (de lo contrario, la fluctuación del reloj hará que esto no sea confiable)
Tenga en cuenta que los retrasos están asociados con los elementos que van en la cola en lugar de la cola misma. Algunos objetos que entran en la cola podrían tener un retraso de cero, mientras que algunos pueden tener un retraso mucho más largo:
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Delayed.html
Con esto en mente, puedo pensar en algunos casos de uso, aunque probablemente serían frágiles y un poco de olor a código con respecto a su flujo de mensajes. Usaría alternativas a todas ellas excepto en situaciones específicas:
1) Control de flujo: sabemos que un pedido tarda 60 segundos en procesarse, así que no lea el siguiente pedido fuera de la cola hasta que el objeto haya estado allí durante al menos 60 segundos.
2) Flujo de mensajes: un sistema altamente asíncrono donde enviamos solicitudes a 2 o 3 servicios externos y luego lanzamos la siguiente tarea para procesar el pedido N segundos después, una vez que sabemos que el primer lote de trabajos al menos habrá tenido la oportunidad de completarse .
3) Agrupación de mensajes: tal vez las órdenes de cierto tipo son explosivas, así que no procesemos las órdenes recibidas en los últimos N segundos para que podamos ver si las órdenes similares llegan poco después y se pueden procesar como un lote en la próxima ejecución.
4) Prioridades de mensajes: diferentes mensajes o diferentes clientes podrían obtener una calidad de servicio ligeramente superior con un retraso menor o cero.
En algunos casos, los objetos que coloque en una cola deben estar en esa cola durante un cierto tiempo antes de que estén listos para su retirada. Aquí es donde usa la clase java.util.concurrent.DelayQueue, que implementa la interfaz BlockingQueue. DelayQueue requiere que los objetos de la cola residan en la cola durante un período de tiempo especificado.
Para ver ejemplos de uso en el mundo real, consulte el artículo Minding the Queue en el sitio devx
... El ejemplo del mundo real en el que pensé para ilustrar esto (que podría darle hambre) involucra muffins. Bueno, Muffin se opone (como estamos hablando de Java, no hay juego de palabras de café). Supongamos que tiene un DelayQueue en el que coloca objetos Muffin ... El método getDelay, en esencia, indica cuánto tiempo queda para que el objeto se mantenga en DelayQueue. Cuando el número devuelto por este método se convierte en cero o menor que cero, el objeto está listo (o en este ejemplo, horneado) y se puede retirar de la cola ...
Como realmente no quieres comer un Muffin que no está completamente cocinado, coloca el Muffin en el DelayQueue durante el tiempo de cocción recomendado ...