Я обнаружил ту же проблему с ArrayBlockingQueue
. Мы хотели, чтобы некоторые дополнительные методы отсутствовали:
void putAll(Collection<? extends E> c)
throws InterruptedException
int drainAtLeastOneTo(@OutputParam Collection<? super E> c)
throws InterruptedException
int drainAtLeastOneTo(@OutputParam Collection<? super E> c, int maxElements)
throws InterruptedException
Некоторые люди рекомендуют использовать BlockingQueue<List<E>>
, но для этого нужны списки malloc'ing. Иногда вы хотите избежать этого. Кроме того, это предполагает, что вы хотите, чтобы производитель и потребитель использовали одинаковые размеры «чанка».
Относительно слива. Опять же, вы можете захотеть иметь несоответствие между размером куска производителя и потребителя. Таким образом, производитель может вставить отдельные позиции, но потребитель работает с партиями. drainTo()
не блокирует, поэтому drainAtLeastOneTo()
было решением.
В конце мы скопировали значение по умолчанию ArrayBlockingQueue
и добавили методы напрямую. Опять же, недостатком является то, что вам нужно работать с конкретным типом вместо интерфейса BlockingQueue
.
Вы можете также рассмотреть вопрос об использовании знаменитого (печально известного?) LMAX Disruptor
, но модель сильно отличается от стандартной BlockingQueue
, поскольку вы не контролируете, когда предметы потребляются.