Являются ли методы вставки и удаления LinkedBlockingQueue потокобезопасными? - PullRequest
52 голосов
/ 23 апреля 2010

Я использую LinkedBlockingQueue между двумя разными потоками. Один поток добавляет данные через add, а другой поток получает данные через take.

У меня вопрос, нужно ли синхронизировать доступ к add и take. Методы вставки и удаления LinkedBlockingQueue безопасны для потоков?

Ответы [ 3 ]

54 голосов
/ 23 апреля 2010

Да.Начиная с документа :

"реализации BlockingQueue являются поточно-ориентированными. Все методы организации очередей достигают своих эффектов атомарно, используя внутренние блокировки или другие формы управления параллелизмом.addAll, containsAll, retainAll и removeAll не обязательно выполняются атомарно, если не указано иное в реализации. Так что, например, addAll (c) может потерпеть неудачу (выбрасывая исключение) после добавления только некоторых элементов в c. "

12 голосов
/ 25 февраля 2014

Да, BlockingQueue методы add() и take() являются потокобезопасными , но с разницей .

Метод

add () и take() использует 2 различных объекта ReentrantLock.

add() метод использует

private final ReentrantLock putLock = new ReentrantLock();

take() метод использует

private final ReentrantLock takeLock = new ReentrantLock();

Следовательно, синхронный доступ к методу add() синхронизирован. Аналогично, одновременный доступ к методу take() равен synchronized.

Но одновременный доступ к методам add() и take() не является synchronized, поскольку они используют 2 различных объекта блокировки (кроме случаев, когда в граничном состоянии очереди полная / пустая).

0 голосов
/ 21 декабря 2015

Просто Да, он определенно безопасен для потоков, иначе он не был бы квалифицирован как кандидат для хранения элемента для ThreadPoolExecutor .

Просто добавьте и получите элемент, не беспокоясь о параллелизме для BlockingQueue.

...