Словарь с замком или словарь Concurency? - PullRequest
6 голосов
/ 26 марта 2012

Что предпочтительнее в многопоточном приложении: Словарь с замком или же Словарь параллелизма

Что является эффективным и почему я должен использовать один или другой?

edit 1: сохранение Guid в качестве ключа и bool в качестве значения.

редактировать 2: более 2 рабочих потоков и один поток пользовательского интерфейса.

Ответы [ 4 ]

6 голосов
/ 29 октября 2012

Я бы сказал, что у вас есть следующие опции.

Некоторые новые классы Framework 4.0:

  • ConcurrentDictionary .Работайте быстро и надежно.
  • ConcurrentBag .Это неупорядоченная коллекция объектов, поэтому она работает быстрее, но подходит, если вам не нужна только сортировка.
  • ConcurrentStack .Это реализация классической структуры данных LIFO (Last-In First-Out), которая обеспечивает потокобезопасный доступ без необходимости внешней синхронизации
  • ConcurrentQueue .Это потокобезопасный FIFO (первый пришел-первый вышел) collection .

Все новые классы 4.0 работают быстрее, но имеют некоторые функции, упомянутые levanovd .Сравнение производительности этих классов вы можете найти здесь .

Некоторые классические решения более ранних версий:

  • Словарь + Монитор.Простой перенос в lock
  • Dictionary + ReaderWriterLock .Лучше, чем предыдущий, потому что получил блокировки чтения и записи.Так что несколько потоков могут читать, а один - писать.
  • Словарь + ReaderWriterLockSlim .Это просто оптимизация предыдущего.
  • Hashtable .По моему опыту, это самый медленный метод.Проверьте метод Hashtable.Synchronized () , это готовое решение от Microsoft.

Если бы у меня было ограничение использования Framework v3.5, я бы использовал Словарь + ReaderWriterLock или ReaderWriterLockSlim .

4 голосов
/ 26 марта 2012

Внимательно прочитайте о ConcurrentDictionary . У него есть некоторые неочевидные особенности.

Вот некоторые из них:

  • Если два потока вызывают AddOrUpdate, нет никаких гарантий относительно того, какой из делегатов фабрики будет вызван, и даже нет гарантии, что если делегат фабрики выдаст какой-то элемент, этот элемент будет сохранен в словаре.
  • Перечислитель, полученный с помощью вызова GetEnumerator, является , а не снимком и может быть изменен во время перечисления (это не вызывает никаких исключений).
  • Keys и Values являются снимками соответствующих коллекций и могут не соответствовать фактическому состоянию словаря.
  • и т.д.

Пожалуйста, прочитайте еще раз о ConcurrentDictionary и решите, подходит ли вам это поведение.

Надеюсь, это поможет!

4 голосов
/ 26 марта 2012

Когда вы реализуете словарь с объектом блокировки, ваша главная задача - безопасность потоков.Таким образом, кажется, concurrentDictionary уже управляет этой проблемой.Я думаю, что нет смысла заново изобретать колесо.

1 голос
/ 26 марта 2012

Я думаю, что оба обеспечат безопасность потока, но использование словаря с объектом блокировки ограничит число потоков, которые могут одновременно обращаться к Словарю, до 1. При использовании словаря одновременного использования вы можете указать уровень одновременного доступа (то есть количество потоков,доступ к словарю одновременно).Если производительность имеет значение, я считаю, что параллельный словарь должен быть вашим выбором.

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