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

时间:2011-09-06 10:06:40

标签: java concurrency 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对象(如果你想要的。)

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

3 个答案:

答案 0 :(得分:12)

也许您可以将某些BlockingQueue(例如ArrayBlockingQueueLinkedBlockingQueue或您正在使用的内容)子类化,添加对侦听器的支持并执行

@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中有要处理的项目,队列使用者就可以继续消耗,而事件侦听器/消费者可以异步执行操作。