параллельная очередь - общий вопрос (описание и использование)

У меня возникли проблемы с пониманием идеи параллельной очереди. Я понимаю, что очередь - это структура данных FIFO, или «первым пришел - первым обслужен».

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

Я был бы очень признателен за общее описание функциональности параллельной очереди. Подобный пост здесь не такой общий, как я надеялся.

Также существует такая вещь, как очередь с одновременным приоритетом? Каково было бы его использование?

Заранее большое спасибо за любые краткие объяснения или полезные ссылки по этой теме.


person Community    schedule 14.10.2009    source источник


Ответы (4)


Мысль о том, что BlockingQueue предлагает небольшие накладные расходы, немного ошибочна. Получение блокировки влечет за собой довольно значительные накладные расходы. Наряду с переключением контекста мы говорим о тысячах инструкций. Не только это, но и прогресс одного потока напрямую влияет на другой поток. Сейчас это не так плохо, как было много лет назад, но по сравнению с неблокирующим режимом это существенно.

BlockingQueue использует блокировки для взаимного исключения

ArrayBlockingQueue, LinkedBlockingQueue, PriorityBlockingQUeue: три очереди блокировки, в то время как

ConcurrentLinkedQueue, java 1.7 LinkedTransferQueue: использует неблокирующий алгоритм очереди Майкла и Скотта.

При умеренной или низкой конкуренции (что является скорее реальным сценарием) неблокирующие очереди значительно превосходят очереди с блокировкой.

И обратите внимание на комментарий Стива об отсутствии узких мест. В условиях сильной конкуренции неблокирующий алгоритм может сдерживать постоянные попытки cas, в то время как блокировка приостанавливает потоки. Затем мы видим, что BlockingQueue в условиях сильной конкуренции немного не выполняет неблокирующую очередь, но такой тип конкуренции ни в коем случае не является нормой.

person Community    schedule 14.10.2009

Под «параллелизмом» я понимаю, что очередь является потокобезопасной. Это не значит, что это будет эффективно. Тем не менее, я мог бы предположить, что очередь Java использует реализацию без блокировки, что означает, что когда два потока одновременно пытаются выполнить push или pop, мало или совсем нет. Обычно происходит то, что они используют атомарную блокировку на уровне ассемблера, которая гарантирует, что один и тот же объект не может быть извлечен дважды.

Однажды я написал очередь FIFO без блокировок (в Delphi), которая работала очень хорошо. Намного более эффективен, чем предыдущая версия, в которой использовались критические разделы. Версия CS остановилась, особенно из-за того, что все потоки пытались получить доступ к очереди. Однако безблокировочная версия не имела узких мест из-за большого количества потоков, обращающихся к ней.

person Steve    schedule 14.10.2009
comment
Получение блокировки для изменения поточно-ориентированной реализации Queue добавляет небольшие накладные расходы, и все реализации BlockingQueue в пакете java.util.concurrent будут использовать по крайней мере одну блокировку (некоторые используют две для установки / снятия). Без блокировок производители / потребители не могут выполнять блокирующие операции ввода / вывода, а массовые операции (например, сток) не могут выполняться атомарно. - person Adamski; 14.10.2009
comment
Я думал, что Java использует очереди без блокировки: java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ - person Steve; 14.10.2009

Вам следует начать с проверки BlockingQueue определение интерфейса, поскольку он является краеугольным камнем для использования очередей для связи между потоками и содержит служебные методы, позволяющие потокам-производителям и потребителям получать доступ к очереди либо блокирующим, либо неблокирующим образом. Это, наряду с потокобезопасным доступом, является моим пониманием того, что представляет собой «параллельная очередь» (хотя я никогда не слышал об этой фразе - BlockingQueue просто существует в java.util.concurrent пакете).

Чтобы ответить на вторую часть вашего вопроса, вам следует изучить реализацию приоритетной очереди PriorityBlockingQueue. Это может быть полезно, если ваши потоки-производители создают задачи с разным приоритетом (например, запросы от «обычных пользователей» и «опытных пользователей»), и вы хотите контролировать порядок, в котором задачи обрабатываются вашим потоком-потребителем. . Одна из возможных ловушек, которую следует избегать - это нехватка задач с низким приоритетом, которые никогда не удаляются из очереди из-за постоянного притока задач с более высоким приоритетом.

person Adamski    schedule 14.10.2009

Просто оставив здесь ссылку на java.util.concurrent package, который, на мой взгляд, содержит очень важную информацию по некоторым поднятым здесь вопросам.

См. Параллельные коллекции и Память Свойства согласованности

person bruno conde    schedule 14.10.2009