13

I need an Object to be asynchronously notified when some BlockingQueue has got an item to give.

I've searched both Javadoc and the web for a pre-made solution, then I ended up with a (maybe naive) solution of mine, here it is:

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

and

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) {
            }
        }
    }
}

Basically, there's a thread blocking on a take() operation of a queue that callbacks a listener object everytime a take() operation succeeds, optionally sending back a special cookie object (ignore it if you want).

Question is: is there any better way to do this? Am I doing some unforgivable mistake (both in concurrency/efficiency and/or code cleanness)? Thanks in advance.

gd1
  • 11,300
  • 7
  • 49
  • 88

3 Answers3

13

Perhaps you could subclass some BlockingQueue (such as ArrayBlockingQueue or LinkedBlockingQueue or what ever you're using), add support for listeners and do

@Override
public boolean add(E o) {
    super.add(o);
    notifyListeners(o);
}
aioobe
  • 413,195
  • 112
  • 811
  • 826
  • 3
    I like it. The only problem is that how can I subclass it, because I don't like to bound to a specific implementation of the BlockingQueue... i.e. if I subclass LinkedBlockingQueue, then I'm bound to this implementation. Should I make a "decorator"? – gd1 Sep 06 '11 at 10:30
0

This reply is too late on the topic, but recently I was working on a similar problem and this is what I used.

When BlockingQueue receives a item/object, I used Spring's SimpleApplicationEventMulticaster which supports Asynchronous event processing. Basically, I published an event and configured it to process asynchronously rather than blocking the same execution thread, allowing the queue consumer to keep consuming as long as there are items to be processed in BlockingQueue, while the event listener/consumer can perform action asynchronously.

AbhiR25
  • 31
  • 1
0

This looks like a good standard pattern for queue blocking and listeners. You make a good choice of making the listener interface. If you are not using the BlockingQueue class (which I am not clear of), the only thing is that you have manage is the correct wait() and notify() for managing the blocking call.

This particular SO Question "A simple scenario using wait() and notify() in java" provides a good overview on wait and notify and the usage related to BlockingQueue

Community
  • 1
  • 1
momo
  • 21,233
  • 8
  • 39
  • 38
  • Can you tell me more on the wait() and notify() usage in this case? – gd1 Sep 06 '11 at 10:22
  • Wait and notify is a method to handle producer consumer problem (such as your blocking queue) prior to introduction of BlockingQueue class that aiobee answered. See this SO question http://stackoverflow.com/questions/2536692/a-simple-scenario-using-wait-and-notify-in-java for exact illustration. If you google "wait and notify Java queue" you will find a lot of similar references such as http://download.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html or http://www.javamex.com/tutorials/synchronization_producer_consumer.shtml – momo Sep 06 '11 at 10:29
  • I knew about wait() and notify() but I thought using a BlockingQueue would handle it out-of-the-box (in fact, in an example you provided, there's a BlockingQueue implementation as a wait()/notify() usage scenario) :) – gd1 Sep 06 '11 at 10:31
  • 1
    Oops... I miss the part you are using the BlockingQueue class already and had thought you are building your own BlockingQueue class. Silly me. I totally deserve a vote down here! – momo Sep 06 '11 at 10:34
  • Never mind! You pointed me some good stuff to review abount wait()/notify(). The topic you linked is interesting. No downvote by me :) – gd1 Sep 06 '11 at 10:35