2011-09-06 9 views
9

Necesito un Object para ser notificado asíncrono cuando un BlockingQueue tiene un artículo para dar.Al ser notificado asincrónicamente de un BlockingQueue que tiene un artículo disponible

He buscado tanto Javadoc y la web para una solución pre-hechos, entonces terminé con una solución (tal vez ingenua) mío, aquí está:

interface QueueWaiterListener<T> { 
    public void itemAvailable(T item, Object cookie); 
} 

y

class QueueWaiter<T> extends Thread { 

    protected final BlockingQueue<T> queue; 
    protected final QueueWaiterListener<T> listener; 
    protected final Object cookie; 

    public QueueWaiter(BlockingQueue<T> queue, QueueWaiterListener<T> listener, Object cookie) { 
     this.queue = queue; 
     this.listener = listener; 
     this.cookie = cookie; 
    } 

    public QueueWaiter(BlockingQueue<T> queue, QueueWaiterListener<T> listener) { 
     this.queue = queue; 
     this.listener = listener; 
     this.cookie = null; 
    } 

    @Override 
    public void run() { 
     while (!isInterrupted()) { 
      try { 
       T item = queue.take(); 
       listener.itemAvailable(item, cookie); 
      } catch (InterruptedException e) { 
      } 
     } 
    } 
} 

Básicamente, hay un hilo de bloqueo en una operación take() de una cola que las devoluciones de llamada un objeto detector cada vez que una operación tiene éxito take(), opcionalmente devolver un objeto especial cookie (ignorarlo si lo desea).

Pregunta es: ¿hay alguna forma mejor de hacerlo? ¿Estoy cometiendo algún error imperdonable (tanto en concurrencia/eficiencia y/o limpieza del código)? Gracias por adelantado.

Respuesta

10

Tal vez usted podría subclase alguna BlockingQueue (como ArrayBlockingQueue o LinkedBlockingQueue o lo que sea que estés usando), añadir soporte para oyentes y do

@Override 
public boolean add(E o) { 
    super.add(o); 
    notifyListeners(o); 
} 
+3

Me gusta. El único problema es que cómo puedo crear una subclase, porque no me gusta vincularme a una implementación específica de BlockingQueue ... es decir, si subclasino LinkedBlockingQueue, entonces estoy obligado a esta implementación. ¿Debo hacer un "decorador"? – gd1

+4

Sí, un decorador parece una buena idea para este problema –

0

Parece un buen patrón estándar para el bloqueo de colas y los oyentes. Usted hace una buena elección para hacer la interfaz del oyente. Si no está utilizando la clase BlockingQueue (que no tengo en claro), lo único que tiene es administrar correctamente wait() y notify() para gestionar la llamada de bloqueo.

Este particular SO Pregunta "A simple scenario using wait() and notify() in java" proporciona una buena visión general de espera y comunicarlo y el uso relacionado con BlockingQueue

+0

¿Puede decirme más sobre el uso de wait() y notify() en este caso? – gd1

+0

Esperar y notificar es un método para manejar el problema del consumidor del productor (como su cola de bloqueo) antes de la introducción de la clase BlockingQueue que aiobee contestó. Vea esta pregunta AS. Http://stackoverflow.com/questions/2536692/a-simple-scenario-using-wait-and-notify-in-java para obtener una ilustración exacta. Si googleas "espera y notifica la cola de Java", encontrarás muchas referencias similares, como http://download.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html o http: //www.javamex. com/tutoriales/synchronization_producer_consumer.shtml – momo

+0

Conocía wait() y notify(), pero pensé que el uso de un BlockingQueue lo manejaría de inmediato (de hecho, en un ejemplo que proporcionó, hay una implementación de BlockingQueue como wait()/notify() escenario de uso) :) – gd1

Cuestiones relacionadas