当某些Object
有要提供的项目时,我需要异步通知BlockingQueue
。
我已经在Javadoc和网络上搜索了预先制定的解决方案,然后我得到了一个(也许是天真的)我的解决方案,这里是:
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
对象(如果你想要的。)
问题是:有没有更好的方法呢?我是否在做一些不可原谅的错误(在并发/效率和/或代码清洁方面)?提前谢谢。
答案 0 :(得分:12)
也许您可以将某些BlockingQueue
(例如ArrayBlockingQueue
或LinkedBlockingQueue
或您正在使用的内容)子类化,添加对侦听器的支持并执行
@Override
public boolean add(E o) {
super.add(o);
notifyListeners(o);
}
答案 1 :(得分:0)
这看起来像是队列阻塞和侦听器的一个很好的标准模式。您可以选择制作侦听器界面。如果您没有使用BlockingQueue类(我不清楚),那么唯一的办法就是管理阻塞调用是正确的wait()
和notify()
。
这个特殊的SO问题"A simple scenario using wait() and notify() in java"提供了关于等待和通知以及与BlockingQueue相关的用法的良好概述
答案 2 :(得分:0)
对于该主题的答复太迟了,但是最近我正在处理类似的问题,这就是我所使用的。
当BlockingQueue接收到一个项目/对象时,我使用了支持异步事件处理的Spring的SimpleApplicationEventMulticaster。基本上,我发布了一个事件并将其配置为异步处理,而不是阻塞相同的执行线程,只要在BlockingQueue中有要处理的项目,队列使用者就可以继续消耗,而事件侦听器/消费者可以异步执行操作。