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


我需要一个 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 对象(如果你愿意,可以忽略它)。

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


4752
2017-09-06 10:06


起源



答案:


也许你可以继承一些 BlockingQueue (如 ArrayBlockingQueue 要么 LinkedBlockingQueue 或者你正在使用什么),添加对听众的支持和做

@Override
public boolean add(E o) {
    super.add(o);
    notifyListeners(o);
}

12
2017-09-06 10:14



我喜欢。唯一的问题是我怎样才能将它子类化,因为我不喜欢绑定到BlockingQueue的特定实现...即如果我将LinkedBlockingQueue子类化,那么我将受到这种实现的约束。我应该做一个“装饰”吗? - gd1
是的,装饰者对这个问题听起来不错 - Steve McLeod


答案:


也许你可以继承一些 BlockingQueue (如 ArrayBlockingQueue 要么 LinkedBlockingQueue 或者你正在使用什么),添加对听众的支持和做

@Override
public boolean add(E o) {
    super.add(o);
    notifyListeners(o);
}

12
2017-09-06 10:14



我喜欢。唯一的问题是我怎样才能将它子类化,因为我不喜欢绑定到BlockingQueue的特定实现...即如果我将LinkedBlockingQueue子类化,那么我将受到这种实现的约束。我应该做一个“装饰”吗? - gd1
是的,装饰者对这个问题听起来不错 - Steve McLeod


这看起来像是队列阻塞和侦听器的良好标准模式。您可以选择制作侦听器界面。如果您没有使用BlockingQueue类(我不清楚),唯一的事情是您管理是正确的 wait() 和 notify() 用于管理阻止呼叫。

这个特别的SO问题 “在java中使用wait()和notify()的简单方案” 提供有关等待和通知以及与BlockingQueue相关的用法的良好概述


0
2017-09-06 10:14



在这种情况下,你能告诉我更多关于wait()和notify()的用法吗? - gd1
Wait和notify是一种在引入aiobee回答的BlockingQueue类之前处理生产者消费者问题(例如阻塞队列)的方法。看到这个问题 stackoverflow.com/questions/2536692/... 准确的说明。如果您谷歌“等待并通知Java队列”,您会发现很多类似的引用,例如 download.oracle.com/javase/tutorial/essential/concurrency/... 要么 javamex.com/tutorials/synchronization_producer_consumer.shtml - momo
我知道wait()和notify(),但我认为使用BlockingQueue会处理它的开箱即用(事实上,在你提供的一个例子中,有一个BlockingQueue实现作为wait()/ notify()用法情景):) - gd1
哎呀......我想念你正在使用BlockingQueue类的部分,并且认为你正在构建自己的BlockingQueue类。傻我。我完全应该在这里投票! - momo
没关系!你指了我一些好东西来审查abount wait()/ notify()。您链接的主题很有趣。没有我的downvote :) - gd1