Потокобезопасные коллекции в.NET

Что является стандартом в настоящее время, когда нужен потокобезопасный набор (например, Set). Синхронизирую ли я это сам или существует коллекция потоков, которая по своей сути безопасна?

4 ответа

Решение

.NET 4.0 Framework представляет несколько поточно-ориентированных коллекций в пространстве имен System.Collections.Concurrent:

ConcurrentBag<Т>;
Представляет потокобезопасную неупорядоченную коллекцию объектов.

ConcurrentDictionary;
Представляет потокобезопасную коллекцию пар ключ-значение, к которым могут обращаться несколько потоков одновременно.

ConcurrentQueue<Т>;
Представляет потокобезопасную коллекцию "первым пришел - первым вышел" (FIFO).

ConcurrentStack<Т>;
Представляет потокобезопасную коллекцию "последний пришел первым" (LIFO).


Другие коллекции в.NET Framework по умолчанию не являются поточно-ориентированными и должны быть заблокированы для каждой операции:

lock (mySet)
{
    mySet.Add("Hello World");
}

До.net 4.0 большинство коллекций в.Net не являются потокобезопасными. Вам придется самостоятельно поработать с синхронизацией: http://msdn.microsoft.com/en-us/library/573ths2x.aspx

Цитата из статьи:

Классы коллекций можно сделать потокобезопасными, используя любой из следующих методов:

Создайте потокобезопасную оболочку, используя метод Synchronized, и обращайтесь к коллекции исключительно через эту оболочку.

Если у класса нет метода Synchronized, производный от класса и реализуйте метод Synchronized, используя свойство SyncRoot.

Используйте механизм блокировки, например оператор блокировки в C# (SyncLock в Visual Basic), в свойстве SyncRoot при доступе к коллекции.

Sync Root Property
Заявление о блокировке

Object thisLock = new Object();
......
lock (thisLock)
{
    // Critical code section
}

В.net 4.0 введено пространство имен System.Collections.Concurrent

Блокирующая коллекция
Concurrent Bag
Параллельная очередь
Словарь одновременно
Ordable Partitioner
Разметка
Partitioner T

.NET 4 предоставляет набор потоковобезопасных коллекций в System.Collections.Concurrent.

В дополнение к очень полезным занятиям в System.Collections.Concurrentодна стандартная методика в сценариях "в основном читают - редко меняют" (или, если есть, однако, частые, но не параллельные записи), которая также применима к.Net, называется копированием при записи.

У него есть пара свойств, которые желательны в высококонкурентных программах:

  • Сами экземпляры объекта коллекции являются неизменяемыми (т. е. потокобезопасными, могут быть безопасно перечислены без блокировки)
  • Модификация может занять столько времени, сколько она хочет, производительность и параллелизм чтения не пострадают
  • может быть реализован в общем, чтобы превратить любую структуру данных, которая не является потокобезопасной, в структуру, которая

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

Редактирование комментария Скотта Чемберлена напомнило мне, что есть еще одно ограничение: если ваши структуры данных огромны и часто происходят модификации, копирование всего при записи может быть непомерным как с точки зрения потребления памяти, так и с точки зрения затрат на копирование ЦП.

Другие вопросы по тегам