LinkedBlockingQueue
блокирует потребителя или производителя, когда очередь пуста или заполнена, и соответствующий поток потребителя / производителя переводится в спящий режим. Но эта блокирующая функция имеет свою цену: каждая операция «положить или взять» является блокировкой между производителями или потребителями (если их много), поэтому в сценариях со многими производителями / потребителями операция может быть медленнее.
ConcurrentLinkedQueue
не использует блокировки, но CAS для операций ввода / вывода, что потенциально снижает конкуренцию со многими потоками производителей и потребителей. Но, будучи структурой данных «без ожидания», ConcurrentLinkedQueue
не будет блокироваться, когда пусто, а это означает, что потребителю придется иметь дело с take()
, возвращающими значения null
с помощью «занятого ожидания», например, с потоком потребителя. поедает процессор.
То, какой из них «лучше», зависит от количества потоков потребителей, от скорости, которую они потребляют / производят, и т. Д. Для каждого сценария необходим эталон.
Один конкретный случай использования, где ConcurrentLinkedQueue
явно лучше, - это когда производители сначала что-то производят и заканчивают свою работу, помещая работу в очередь , и только после потребители начинают потреблять, зная, что они будет сделано, когда очередь пуста. (здесь нет параллелизма между производителем-потребителем, а только между производителем-производителем и потребителем-потребителем)