По сути, разница между ними заключается в характеристиках производительности и поведении блокировки.
Если взять самый простой из первых, ArrayBlockingQueue
- это очередь фиксированного размера. Поэтому, если вы установите размер 10 и попытаетесь вставить 11-й элемент, оператор вставки будет блокироваться, пока другой поток не удалит элемент. Вопрос справедливости заключается в том, что происходит, если несколько потоков пытаются вставить и удалить одновременно (другими словами, в течение периода, когда очередь была заблокирована). Алгоритм справедливости гарантирует, что первый запрашивающий поток является первым получающим потоком. В противном случае данный поток может ждать дольше, чем другие потоки, что приводит к непредсказуемому поведению (иногда один поток занимает несколько секунд, потому что другие потоки, которые были запущены позже, обрабатываются первыми). Компромисс заключается в том, что для управления честностью требуются дополнительные затраты, что замедляет пропускную способность.
Самое важное различие между LinkedBlockingQueue
и ConcurrentLinkedQueue
состоит в том, что если вы запрашиваете элемент у LinkedBlockingQueue
, а очередь пуста, ваш поток будет ждать, пока что-то там будет. ConcurrentLinkedQueue
сразу же вернется с поведением пустой очереди.
От чего зависит, нужна ли вам блокировка. Там, где у вас много производителей и один потребитель, это звучит так. С другой стороны, когда у вас много потребителей и только один производитель, вам может не потребоваться блокирующее поведение, и вы можете просто попросить потребителей проверить, пуста ли очередь, и двигаться дальше, если она есть.