Being asynchronously notified of a BlockingQueue having an item available

gd1 picture gd1 · Sep 6, 2011 · Viewed 10.5k times · Source

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.

Answer

aioobe picture aioobe · Sep 6, 2011

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