Этот вопрос заслуживает лучшего ответа.
Java ConcurrentLinkedQueue
основан на знаменитом algorithm by Maged M. Michael and Michael L. Scott для non-blocking lock-free очередей.
«Non-blocking» как термин здесь для конкурирующего ресурса (наша очередь) означает, что независимо от того, что делает планировщик платформы, например, прерывание потока, или если поток, о котором идет речь, слишком медленный, другие конфликтующие темы потому что тот же ресурс все равно сможет прогрессировать. Например, если блокировка задействована, поток, удерживающий блокировку, может быть прерван, и все потоки, ожидающие блокировки, будут заблокированы. Встроенные блокировки (ключевое слово synchronized
) в Java также могут иметь суровое наказание за производительность - например, когда участвует biased locking, и у вас есть конфликт, или после того, как VM решает «раздуть» блокировку после периода отсрочки отжима и блокировать конфликтующие потоки ... поэтому во многих контекстах (сценариях с низким/средним соперничеством) выполнение сравнений и наборов по атомным ссылкам может быть намного более эффективным, и это именно то, что делают многие неблокирующие структуры данных.
Java ConcurrentLinkedQueue
не только не блокирует, но обладает прекрасным свойством, которое производитель не поддерживает с потребителем. В одном сценарии производителя/единого потребителя (SPSC) это действительно означает, что говорить об этом не будет. В сценарии множественного производителя/единого потребителя потребитель не будет бороться с производителями. У этой очереди есть соперничество, когда несколько продюсеров пытаются offer()
, но это параллелизм по определению. Это в основном общая цель и эффективная неблокирующая очередь.
Как для него не быть BlockingQueue
, ну, блокируя нить, чтобы ждать в очереди, является причудливо ужасным способом проектирования параллельных систем. Не. Если вы не можете понять, как использовать ConcurrentLinkedQueue
в сценарии «потребитель/производитель», просто переключитесь на абстракции более высокого уровня, например, на хорошую актерскую структуру.
Спасибо Jon - я не заметил. Итак, где/почему вы используете ConcurrentLinkedQueue? – Adamski
Когда вам нужно получить доступ к очереди из большого количества потоков, но вам не нужно «ждать» на ней. –
«ConcurrentLinkedQueue» также полезен, если ваш поток проверяет несколько очередей. Например, на сервере с несколькими арендаторами. Исходя из соображений изоляции, вы не используете одну блокирующую очередь и дискриминатор арендатора. – LateralFractal