Ограниченная BlockingQueue, которая не блокирует - PullRequest
1 голос
/ 05 августа 2009

Название этого вопроса заставляет меня сомневаться, существует ли оно, но все же:

Меня интересует, есть ли в Java реализованная BlockingQueue , которая ограничена по размеру и никогда не блокируется, а скорее выдает исключение при попытке поставить в очередь слишком много элементов.

Редактировать - Я передаю BlockingQueue Исполнителю, который, я полагаю, использует его метод add (), а не offer (). Можно написать BlockingQueue, который обернет другой BlockingQueue и делегировать вызовы add () в offer ().

Ответы [ 4 ]

4 голосов
/ 05 августа 2009

Редактировать: Исходя из вашего нового описания, я считаю, что вы задаете неправильный вопрос. Если вы используете Executor, вы, вероятно, должны определить пользовательский RejectedExecutionHandler вместо изменения очереди. Это работает только в том случае, если вы используете ThreadPoolExecutor, но если это не так, вероятно, было бы лучше изменить Executor, а не очередь.

По моему мнению, было бы ошибкой переопределять предложение и заставлять его вести себя как добавление. Интерфейсные методы составляют контракт. Код клиента, который использует блокирующие очереди, зависит от методов, которые фактически выполняют то, что указано в документации. Нарушение этого правила открывает мир боли. И это не элегантно.


Метод add () в BlockingQueues делает это, но у них также есть метод offer () , который обычно является лучшим выбором. Из документации к предложению ():

Вставляет указанный элемент в хвост этой очереди, если это возможно сделать это немедленно, не превышая емкость очереди, возвращая истину в случае успеха и ложь, если эта очередь полный. Этот метод обычно предпочтительнее метода add (E), который может не удается вставить элемент только бросить исключение.

Это работает для всех таких очередей независимо от конкретной реализации (ArrayBlockingQueue, LinkedBlockingQueue и т. Д.)

BlockingQueue<String> q = new LinkedBlockingQueue<String>(2);
System.out.println(q.offer("foo")); // true
System.out.println(q.offer("bar")); // true
System.out.println(q.offer("baz")); // false
0 голосов
/ 22 октября 2010

В простом сценарии использования для получения запросов, выполняемых из исходной базы данных в пакете (исполнитель), обогащения в пакете и помещения в другую базу данных (исполнитель), вы захотите выполнять запросы только так быстро, как они помещаются в другую базу данных. В этом случае исполнитель dest должен принять ограниченного по блокировке исполнителя для решения проблемы, чем продолжать опрос и проверку количества выполненных запросов для выполнения большего количества запросов.

упс, см. Мой оставшийся комментарий:

0 голосов
/ 22 октября 2010

это печально, вы не можете заблокировать, есть так много вариантов использования, когда вы хотите заблокировать, сама идея предоставления вашей собственной ограниченной очереди блокировки исполнителю не имеет смысла.

public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {
            if (runState == RUNNING && workQueue.***offer***(command)) {
                if (runState != RUNNING || poolSize == 0)
                    ensureQueuedTaskHandled(command);
            }
            else if (!addIfUnderMaximumPoolSize(command))
                reject(command); // is shutdown or saturated
        }
    }
0 голосов
/ 05 августа 2009

Можно написать BlockingQueue, который оборачивает другой BlockingQueue и делегаты звонков, чтобы добавить (), чтобы предложить ().

Если это должен быть вопрос ... ответ - «Да», но вы можете сделать это более аккуратно, создав подкласс, который переопределяет add (). Единственный улов (в обоих случаях) заключается в том, что ваша версия add не может генерировать какие-либо отмеченные исключения, которые не входят в метод, который вы переопределяете, поэтому ваше исключение «блокировать» необходимо будет не проверять.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...