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

问题描述 投票:11回答:3

当某些Object有要提供的项目时,我需要异步通知BlockingQueue

我已经在Javadoc和Web上搜索了一个预制的解决方案,然后最终得到了我的(可能是幼稚的)解决方案,这里是:

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对象(如果需要,可以忽略它)。

问题是:还有更好的方法吗?我是否在犯一些不可原谅的错误(在并发/效率和/或代码清除方面)?预先感谢。

java concurrency blockingqueue
3个回答
12
投票

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

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

0
投票

这似乎是队列阻塞和侦听器的一种很好的标准模式。您可以选择建立侦听器界面。如果您没有使用BlockingQueue类(我不清楚),那么您唯一要管理的是用于管理阻塞调用的正确wait()notify()

这个特定的SO问题"A simple scenario using wait() and notify() in java"提供了有关等待和通知以及与BlockingQueue相关的用法的很好的概述


0
投票

此回复在该主题上为时已晚,但是最近我正在处理类似的问题,这就是我所使用的。

当BlockingQueue接收到一个项目/对象时,我使用了Spring的SimpleApplicationEventMulticaster,它支持异步事件处理。基本上,我发布了一个事件并将其配置为异步处理,而不是阻塞相同的执行线程,只要在BlockingQueue中有要处理的项目,队列使用者就可以继续消耗,而事件侦听器/消费者可以异步执行操作。

© www.soinside.com 2019 - 2024. All rights reserved.