Что такое & ldquo; неблокирующая & rdquo; параллелизм и чем он отличается от обычного параллелизма?

В дополнение к синтаксическим и эксплуатационным свойствам существует также семантическая разница.

Делегаты - это концептуально, функциональные шаблоны; то есть они выражают контракт, который должна придерживаться функция, чтобы быть рассмотренной «типом» делегата.

События представляют ... ну, события. Они предназначены для предупреждения кого-то, когда что-то происходит, и да, они придерживаются определения делегата, но это не одно и то же.

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

37
задан Gray 29 June 2012 в 18:09
поделиться

5 ответов

Что такое неблокирующий параллелизм и чем он отличается.

Формально:

В информатике неблокирующая синхронизация гарантирует, что потоки , конкурирующие за общий ресурс, не будут выполняться бесконечно отложено по взаимному исключению. неблокирующий алгоритм не требует блокировки, если есть гарантированный прогресс в масштабе всей системы ; без ожидания, если также есть гарантированный прогресс для каждого потока. (wikipedia)

Неофициальный: одна из наиболее выгодных особенностей неблокирования по сравнению с блокировкой заключается в том, что потоки не должны быть приостановлены / выведены из спящего режима ОС. Такие накладные расходы могут составлять от 1 мс до нескольких 10 мс, поэтому их устранение может значительно повысить производительность.В java это также означает, что вы можете использовать несправедливую блокировку, которая может иметь гораздо большую пропускную способность системы, чем справедливая блокировка.

Я слышал, что это доступно на Java. Есть ли какие-то сценарии, в которых мы должны использовать эту функцию

Да, из Java5. Фактически, в Java вы должны в основном стараться максимально удовлетворить свои потребности с помощью java.util.concurrent (который часто использует неблокирующий параллелизм, но в большинстве случаев вам не нужно явно беспокоиться). Только если у вас нет другого варианта, вы должны использовать синхронизированные оболочки (.synchronizedList () и т. Д.) Или ключевое слово synchronize вручную. Таким образом, вы в большинстве случаев получаете более удобные в обслуживании и более производительные приложения.

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

Есть ли разница / преимущество в использовании одного из этих методов для коллекции . Каковы компромиссы

Оба имеют одинаковое поведение (байтовый код должен быть одинаковым). Но я предлагаю использовать Collections.synchronized , потому что он короче = меньше места, чтобы облажаться!

18
ответ дан 27 November 2019 в 03:48
поделиться

1) Неблокирующая синхронизация означает, что риск взаимоблокировок устранен. Ни один поток не будет ждать, пока блокировка будет удерживаться другим потоком «вечно».

2) Подробнее об алгоритмах неблокирующей синхронизации в java.

3
ответ дан 27 November 2019 в 03:48
поделиться
  1. Википедия - отличный ресурс для любого студента, изучающего информатику. Вот статья о неблокирующей синхронизации - http://en.wikipedia.org/wiki/Non-blocking_synchronization

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

  3. Вы должны использовать блокировку (т.е. синхронизированный (список)) только тогда, когда это необходимо, из-за времени, необходимого для получения блокировки. В Java Vector - это потокобезопасная структура данных, очень похожая на ArrayList в Java.

2
ответ дан 27 November 2019 в 03:48
поделиться

1) Что такое неблокирующий параллелизм и чем он отличается.

Задача (поток) является неблокирующей, если она не заставляет другие задачи (потоки) ждать завершения этой задачи.

2) Я слышал, что это доступно в Java. Есть ли какие-то конкретные сценарии, в которых мы должны использовать эту возможность

Java поддерживает многопоточность. Вы можете воспользоваться ею для одновременного выполнения нескольких задач. При хорошем написании и реализации это может ускорить программу при выполнении на машине с несколькими логическими процессорами. Для начала, существуют java.lang.Runnable и java.lang.Thread как низкоуровневые реализации параллелизма. Затем есть высокоуровневый параллелизм в виде java.util.concurrent API.

3) Есть ли разница/преимущество в использовании одного из этих методов для коллекции. Каковы компромиссы

Я бы использовал Collections#synchronizedList(), не только потому, что это более надежно и удобно, но и потому, что Map не является List. Нет необходимости пытаться вырастить такую карту, когда API уже предлагает такую возможность.


Тем не менее, существует учебник Sun о параллелизме. Я рекомендую вам пройти его.

10
ответ дан 27 November 2019 в 03:48
поделиться

1] Что такое неблокирующий параллелизм и чем он отличается.

Как уже упоминалось, неблокирование - это способ сказать «отсутствие тупиков» (это означает, что у нас не должно быть условия, при котором выполнение полностью останавливается, пока потоки заблокированы, ожидая доступа).

Под «параллелизмом» подразумевается то, что несколько вычислений выполняются одновременно (одновременно).

2] Я слышал, что это доступно на Java. Существуют ли какие-либо конкретные сценарии, в которых мы должны использовать эту функцию

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

3] Есть ли разница / преимущество в использовании одного из этих методов для коллекции . Каковы компромиссы

.

Использование блока synchronized (list) гарантирует, что все действия, выполняемые в блоке, рассматриваются как атомарные. Другими словами, до тех пор, пока мы получаем доступ к списку только из синхронизированных (списковых) блоков, все обновления в списке будут отображаться так, как если бы они произошли в одно и то же время внутри блока.

Объект synchronizedList (или synchronizedMap) только обеспечивает потокобезопасность отдельных операций. Это означает, что две вставки не будут выполняться одновременно.Рассмотрим следующий цикл:

for(int i=0; i < 4; i++){
    list.add(Integer.toString(i));
}

Если используемый список был synchronizedList, и этот цикл был выполнен в двух разных потоках, тогда мы можем получить {0,0,1,2,1,3,2,3} в наш список или какая-то другая перестановка.

Почему? Что ж, мы гарантируем, что поток 1 добавит 0-3 в этом порядке, и нам гарантируется то же самое, что и поток 2, однако у нас нет гарантии, как они будут чередоваться.

Однако, если мы заключим этот список в блок synchronized (list):

synchronized(list){
    for(int i=0; i < 4; i++){
        list.add(Integer.toString(i));
    }
}

Нам гарантируется, что вставки из потока 1 и потока 2 не будут чередоваться, но все они произойдут одновременно. Наш список будет содержать {0,1,2,3,0,1,2,3}. Другой поток будет заблокирован, ожидая в списке, пока не завершится первый поток. У нас нет гарантии, какой поток будет первым, но мы гарантируем, что он завершится раньше, чем начнется другой.

Итак, некоторые компромиссы:

  • С syncrhonizedList вы можете вставить без явного использования синхронизированного блока .
  • SyncrhonizedList может дать вам ложное чувство безопасности, поскольку вы можете наивно полагать, что последовательные операции в одном потоке будут атомарными, когда только отдельные операции являются атомарными
  • Использование синхронизированного (списка) блока должно выполняться с осторожностью, потому что мы можем создать тупик (подробнее ниже).

Мы можем создать тупик, когда каждый из двух (или более) потоков ожидает подмножества ресурсов, принадлежащих другому. Если, например, у вас есть два списка: userList и movieList.

Если поток 1 сначала получает блокировку для userList, затем movieList, но поток 2 выполняет эти шаги в обратном порядке (получает блокировку для movieList перед userList), то мы открылись для тупиковой ситуации. Рассмотрим следующий ход событий:

  1. Поток 1 получает блокировку для userList
  2. Поток 2 получает блокировку для movieList
  3. Поток 1 пытается получить блокировку для movieList, ожидает освобождения потока 2
  4. Поток 2 пытается получает блокировку для userList, ожидает освобождения потока 1

Оба потока ждут другого, и ни один из них не может двигаться вперед. Это сценарий блокировки, и поскольку ни один из них не откажется от своего ресурса, мы зашли в тупик.

4
ответ дан 27 November 2019 в 03:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: