异步通知具有可用项目的BlockingQueue

gd1*_*gd1 11 java concurrency blockingqueue

Object当一些BlockingQueue人有一个项目给我时,我需要异步通知.

我已经在Javadoc和网络上搜索了一个预先制定的解决方案,然后我最终得到了一个(也许是天真的)我的解决方案,这里是:

interface QueueWaiterListener<T> {
    public void itemAvailable(T item, Object cookie);
}
Run Code Online (Sandbox Code Playgroud)

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) {
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

基本上,在take()每次take()操作成功时回调一个侦听器对象的队列操作都有一个线程阻塞,可选地发回一个特殊cookie对象(如果你愿意,可以忽略它).

问题是:有没有更好的方法呢?我是否在做一些不可原谅的错误(在并发/效率和/或代码清洁方面)?提前致谢.

aio*_*obe 12

也许你可以将一些子类化BlockingQueue(例如ArrayBlockingQueue或者LinkedBlockingQueue或者你正在使用的东西),添加对听众的支持和做

@Override
public boolean add(E o) {
    super.add(o);
    notifyListeners(o);
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,装饰者对这个问题听起来不错 (4认同)
  • 我喜欢.唯一的问题是我怎样才能将它子类化,因为我不喜欢绑定到BlockingQueue的特定实现...即如果我将LinkedBlockingQueue子类化,那么我将受到这种实现的约束.我应该做一个"装饰"吗? (3认同)