Почему ArrayBlockingQueue называется ограниченной очередью, а LinkedBlockingQueue - неограниченной блокирующей очередью?

насколько я знаю, как связанный список, так и массив могут расти без границ или я ошибаюсь ? Но когда я пройду через документация в службе исполнителя Я вижу так :

неограниченные очереди. Используя неограниченной очередью (например, LinkedBlockingQueue без предопределенной емкости) вызовет новые задачи для ожидания в очереди, когда все потоки corePoolSize заняты. Таким образом, будет создано не более потоков corePoolSize. (И поэтому значение maximumPoolSize не имеет никакого эффекта.)

Так же Unbounded Queue свойство изменяется, когда LinkedBlockingQueue имеет определенную емкость ?

и это написано для ArrayBlockingQueue:

ограниченные очереди. Ограниченная очередь (например, ArrayBlockingQueue) помогает предотвратить исчерпание ресурсов при использовании с finite maximumPoolSizes, но может быть сложнее настроить и контролировать. Очередь размеры и максимальные размеры пула могут быть проданы друг для друга: использование большие очереди и небольшие пулы минимизируют использование ЦП, ресурсов ОС и контекстно-коммутационные накладные расходы, но могут привести к искусственно низким пропускная способность. Если задачи часто блокируются (например, если они являются I / O bound), система может планировать время для большего количества потоков, чем иначе вы позволите. Использование небольших очередей обычно требует больших размеры пула, который держит процессоры более загруженными, но может столкнуться с неприемлемым планирование накладных расходов, которые также уменьшаются пропускная способность.

5 ответов


почему вы думаете, что ArrayBlockingQueue может расти без предела? От его документации:

Это классический "ограниченный буфер", в котором массив фиксированного размера содержит элементы, вставленные производителями и извлеченные потребителями. После создания потенциала его невозможно увеличить. Попытки поместить элемент в полную очередь приведут к блокировке операции; попытки взять элемент из пустой очереди будут аналогичны блок.

вы путаетесь с ArrayList случайно-который также поддерживается массивом, но который расширяет это по мере необходимости?

таким образом, свойство неограниченной очереди изменяется, когда LinkedBlockingQueue имеет определенную емкость ?

Да, поэтому он описывается как "необязательно ограниченный" в его Javadocs. Кроме того, в документах указано, что (акцент мой):

необязательный аргумент конструктора с привязкой к емкости служит способом предотвращения чрезмерного расширения очереди. Емкость, если она не указана, равна Integer.МАКСИМАЛЬНОЕ ЗНАЧЕНИЕ. Связанные узлы динамически создаются при каждой вставке если это не приведет к очереди выше емкости.


из documentataion для ArrayBlockingQueue

ограниченная блокирующая очередь, поддерживаемая массивом. Эта очередь заказывает элементы FIFO (first-in-first-out). Глава очереди - это элемент, который находился в очереди самое долгое время. Хвост очереди - это элемент, который находился в очереди самое короткое время. Новые элементы вставляются в хвост очереди, а операции извлечения очереди получают элементы во главе очереди.

Если вы заметили, что все конструкторы ArrayBlockingQueue принимают емкость, потому что этот класс был разработан для ограничения. Этот выбор был сделан потому, что если вы хотите параллельную очередь, вам, вероятно, не нужны накладные расходы, связанные с изменением размера ArrayList. Следовательно, если вы хотите неограниченную очередь LinkedBlockingQueue-лучший вариант, поскольку он не включает эти накладные расходы.


на javadoc для LinkedBlockingQueue говорит:

необязательно ограниченная очередь блокировки на основе связанных узлов.[...]

необязательный аргумент конструктора с привязкой к емкости служит способом предотвращение чрезмерного расширения очереди. Емкость, если она не указана, равное число.МАКСИМАЛЬНОЕ ЗНАЧЕНИЕ.

на javadoc из ArrayBlockingQueue говорит:

ограниченная блокирующая очередь, поддерживаемая матрица.[...]

Это классический "ограниченный буфер", в котором хранится массив фиксированного размера элементы, вставленные производителями и извлеченные потребителями. Однажды созданный, емкость не может быть увеличена

таким образом, связанная блокирующая очередь может быть ограничена ou неограниченной, тогда как ArrayBlockingQueue всегда ограничен.


насколько я знаю, как связанный список, так и массив могут расти без границ или я ошибаюсь

связанный список как неограниченный размер. Массив имеет фиксированный размер. ArrayList обертывает массив и заменяет его, когда ему нужен больший.

также изменяется свойство неограниченной очереди, когда LinkedBlockingQueue имеет определенную емкость

когда LinkedBlockingQueue имеет максимальную емкость, она ограничена, но не используется этот путь по умолчанию.


другой ответ очень правильный! Я предлагаю другой способ объяснения. ну, меня также смущает термин "несвязанный и связанный". вы можете посмотреть исходный код сдуло.

    /** The queued items */
final Object[] items;

/** items index for next take, poll, peek or remove */
int takeIndex;

/** items index for next put, offer, or add */
int putIndex;

/** Number of elements in the queue */
int count;

из исходного кода, мы видим массив финал, так что мы не можем изменить размер массива. если использовать LinkedBlockingQueue, мы всегда можем добавить больше элементов...и в исходном коде, следующая ссылка не является окончательным. Обратите внимание, в теории, LinkedBlockingQueue не безграничное. потому что это может только хранить MAX_INTEGER минус 8 элементов. из javadoc неограниченная очередь является PriorityBlockingQueue. но PriorityBlockingQueue также может хранить только элементы MAX_INTEGER -8. поэтому я думаю, что нет идеальной неограниченной очереди...