当某些Object
有要提供的项目时,我需要异步通知BlockingQueue
。
我已经在Javadoc和Web上搜索了一个预制的解决方案,然后最终得到了我的(可能是幼稚的)解决方案,这里是:
interface QueueWaiterListener<T> {
public void itemAvailable(T item, Object cookie);
}
和
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) {
}
}
}
}
[基本上,队列的take()
操作上有一个线程阻塞,每次take()
操作成功时都会回调一个侦听器对象,可以选择发送回一个特殊的cookie
对象(如果需要,可以忽略它)。
问题是:还有更好的方法吗?我是否在犯一些不可原谅的错误(在并发/效率和/或代码清除方面)?预先感谢。
也许您可以将某些BlockingQueue
子类化(例如ArrayBlockingQueue
或LinkedBlockingQueue
或您正在使用的东西),添加对侦听器的支持并执行
@Override
public boolean add(E o) {
super.add(o);
notifyListeners(o);
}
这似乎是队列阻塞和侦听器的一种很好的标准模式。您可以选择建立侦听器界面。如果您没有使用BlockingQueue类(我不清楚),那么您唯一要管理的是用于管理阻塞调用的正确wait()
和notify()
。
这个特定的SO问题"A simple scenario using wait() and notify() in java"提供了有关等待和通知以及与BlockingQueue相关的用法的很好的概述
此回复在该主题上为时已晚,但是最近我正在处理类似的问题,这就是我所使用的。
当BlockingQueue接收到一个项目/对象时,我使用了Spring的SimpleApplicationEventMulticaster,它支持异步事件处理。基本上,我发布了一个事件并将其配置为异步处理,而不是阻塞相同的执行线程,只要在BlockingQueue中有要处理的项目,队列使用者就可以继续消耗,而事件侦听器/消费者可以异步执行操作。