Получать асинхронное уведомление о наличии элемента BlockingQueue - PullRequest
11 голосов
/ 06 сентября 2011

Мне нужно 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 (игнорируйте его, если хотите).

Вопрос: есть ли лучший способ сделать это? Я делаю какую-то непростительную ошибку (как в параллелизме / эффективности, так и / или чистоте кода)? Заранее спасибо.

Ответы [ 2 ]

12 голосов
/ 06 сентября 2011

Возможно, вы могли бы создать подкласс для некоторого BlockingQueue (например, ArrayBlockingQueue или LinkedBlockingQueue или что-либо, что вы используете), добавить поддержку слушателей и сделать

@Override
public boolean add(E o) {
    super.add(o);
    notifyListeners(o);
}
0 голосов
/ 06 сентября 2011

Это похоже на хороший стандартный шаблон для блокировки очереди и слушателей.Вы делаете хороший выбор, делая интерфейс слушателя.Если вы не используете класс BlockingQueue (о котором мне не ясно), единственное, что вам нужно, - это правильные wait() и notify() для управления вызовом блокировки.

Этот конкретный SOВопрос «Простой сценарий с использованием wait () и notify () в Java» дает хороший обзор ожидания и уведомления, а также использования, связанного с BlockingQueue

...