Ответ 1
Ограниченная емкость BlockingQueue
также полезна, если вы хотите активировать какой-то запрос. С неограниченной очередью производители могут значительно опережать потребителей. Задачи в конечном итоге будут выполнены (если их так много, что они вызывают OutOfMemoryError
), но продюсер может давно отказаться, поэтому усилия будут потрачены впустую.
В подобных ситуациях может быть лучше сообщить потенциальному производителю, что очередь заполнена, и быстро отказаться от сбоя. Например, производитель может быть веб-запросом с пользователем, который не хочет ждать слишком долго, и хотя он не будет потреблять много циклов процессора во время ожидания, он использует ограниченные ресурсы, такие как сокет и некоторая память, Отказ от выполнения задач, которые были поставлены в очередь, дает больше шансов закончить своевременно.
Что касается измененного вопроса, который я интерпретирую как "Что такое хорошая коллекция для хранения объектов в пуле?"
Неограниченный LinkedBlockingQueue
является хорошим выбором для многих пулов. Однако, в зависимости от стратегии управления пулом, может работать ConcurrentLinkedQueue
.
В приложении для объединения блокировка "put" не подходит. Управление максимальным размером очереди - это задание диспетчера пулов - он решает, когда создавать или уничтожать ресурсы для пула. Клиенты бассейна заимствуют и возвращают ресурсы из пула. Добавление нового объекта или возврат ранее заимствованного объекта в пул должны быть быстрыми, неблокирующими. Таким образом, ограниченная емкость очереди не является хорошим выбором для пулов.
С другой стороны, при извлечении объекта из пула большинство приложений хотят подождать, пока не будет доступен ресурс. Операция "взять", которая блокирует, по крайней мере временно, намного эффективнее, чем "ожидание ожидания" и повторяет опрос до тех пор, пока ресурс не будет доступен. LinkedBlockingQueue
- хороший выбор в этом случае. Заемщик может неограниченно блокировать take
или ограничить время, которое он хочет заблокировать с помощью poll
.
Менее распространенный случай, когда клиент не хочет блокировать вообще, но имеет возможность создать ресурс для себя, если пул пуст. В этом случае a ConcurrentLinkedQueue
является хорошим выбором. Это своего рода серая область, где было бы неплохо совместно использовать ресурс (например, память), но скорость еще важнее. В худшем случае это вырождается в каждую нить, имеющую собственный экземпляр ресурса; то было бы более эффективно не пытаться делиться между потоками.
Обе эти коллекции обеспечивают хорошую производительность и простоту использования в параллельном приложении. Для несовлокальных приложений, ArrayList
трудно превзойти. Даже для коллекций, которые растут динамически, накладные расходы на один элемент LinkedList
позволяют ArrayList
с некоторыми пустыми слотами оставаться конкурентоспособными по памяти.