异步通知阻止队列具有可用的项目

2022-09-04 21:30:16

我需要一个,当有些人有一个项目要给时,我会得到异步通知。ObjectBlockingQueue

我已经在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

问题是:有没有更好的方法来做到这一点?我是否犯了一些不可原谅的错误(无论是在并发性/效率和/或代码清理方面)?提前致谢。


答案 1

也许你可以子类化一些(如或或你正在使用的任何),添加对侦听器的支持,并做BlockingQueueArrayBlockingQueueLinkedBlockingQueue

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

答案 2

这看起来像是队列阻塞和侦听器的良好标准模式。您为制作侦听器接口做出了很好的选择。如果您没有使用BlocktingQueue类(我不清楚),唯一的事情就是您管理是正确的,并且用于管理阻塞调用。wait()notify()

这个特定的SO问题“在java中使用wait()和inform()的简单场景”提供了有关等待和通知以及与BlocktingQueue相关的用法的良好概述


推荐