LinkedBlockingQueue
blokuje konsumenta lub producenta, gdy kolejka jest pusta lub pełna, a odpowiedni wątek konsumenta / producenta jest uśpiony. Ale ta funkcja blokowania wiąże się z kosztami: każda operacja typu put lub take jest blokowana między producentami lub konsumentami (jeśli jest ich wielu), więc w scenariuszach z wieloma producentami / konsumentami operacja może być wolniejsza.
ConcurrentLinkedQueue
nie używa blokad, ale CAS w swoich operacjach typu put / take potencjalnie redukuje rywalizację z wieloma wątkami producentów i konsumentów. Ale bycie „wolne” czekać strukturę danych, ConcurrentLinkedQueue
nie będzie blokować gdy pusty, co oznacza, że konsument będzie musiał uporać się z take()
powracającym null
wartości przez „zajęty oczekiwania”, na przykład, z gwintem konsument pochłania CPU.
Zatem, który z nich jest „lepszy”, zależy od liczby wątków konsumenckich, tempa ich konsumpcji / produkcji itp. Dla każdego scenariusza potrzebny jest punkt odniesienia.
Jeden szczególny przypadek użycia, w którym ConcurrentLinkedQueue
jest wyraźnie lepiej, to sytuacja, gdy producenci najpierw coś wytwarzają i kończą pracę, umieszczając pracę w kolejce i dopiero po tym, jak konsumenci zaczną konsumować, wiedząc, że zrobią to, gdy kolejka będzie pusta. (tutaj nie ma współbieżności między producentem-konsumentem, ale tylko między producentem-producentem a konsumentem-konsumentem)