Reputation: 11403
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.
Upvotes: 13
Views: 11951
Reputation: 31
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.
Upvotes: 0
Reputation: 420991
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);
}
Upvotes: 13
Reputation: 21343
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
Upvotes: 0