Будет ли когда-нибудь блокироваться ConcurrentLinkedQueue # poll ()? - PullRequest
2 голосов
/ 19 февраля 2009

Мой поток работает вечно и вызывает ConcurrentLinkedQueue # poll () после ConcurrentLinkedQueue # peek ().

Но при некоторых условиях нить кажется зависшей. Я знаю, что это немного расплывчато но могут ли люди подтвердить для меня, что методы poll () или peek () блокируют НИКОГДА . Спасибо.

Ответы [ 3 ]

2 голосов
/ 19 февраля 2009

Насколько я могу судить, ConcurrentLinkedQueue является реализацией "без ожидания".

Поэтому я должен предположить, что каждый независимый вызов poll() или peek() будет НИКОГДА не блокировать .

Атомарные операции над этой коллекцией синхронизируются, и каждый отдельный вызов очереди гарантированно безопасен для потоков.

Должна быть проблема с вашим кодом. Например, если вы делаете:

Object obj;

if (queue.peek() != null)
   obj = queue.poll()

Не гарантирует, что obj не будет null.

0 голосов
/ 19 февраля 2009

Я не верю, что ваша проблема связана с этим, но poll () и peek () могут (по крайней мере теоретически) заблокировать:

Как видно из названия, ConcurrentLinkedQueue реализован в виде связанного списка. При опросе или просмотре реализация пытается начать с головы и перебирает связанные узлы, пытаясь найти узел, который не был удален. Если он находит непустой узел, он возвращает это, если он достигает конца, он возвращает, что очередь пуста, но если он находит удаленный узел, он повторяет попытку.

Итак, рассмотрим эту последовательность. P является потоком производителя, и у нас есть два потребительских потока C1 и C2:

P:  queue.add()
C1: starts queue.poll(), begins to inspect first node
C2: completes a queue.poll() removing the item.
P:  queue.add()
C1: continues inspecting the first node, notes that it is deleted. 
      Restarts and begins to inspect the new first node.
C2: completes a queue.poll() removing the item.
P:  queue.add()
C1: continues inspecting the first node, notes that it is deleted. 
      Restarts and begins to inspect the new first node.
etc.

Так что poll () и peek () будут блокироваться, пока не смогут определить, пуста очередь или нет.

Но если вы не используете какие-то очень странные приоритеты потоков, этот сценарий весьма маловероятен, и я бы порекомендовал вам поискать ошибку в другом месте.

0 голосов
/ 19 февраля 2009

Согласно Javadoc, peek () и poll () никогда не должны блокироваться. Я быстро провел тест производителя и потребителя и не получил блокировку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...