Почему List <T>не является потокобезопасным? - PullRequest
42 голосов
/ 01 апреля 2009

со следующего сайта:

http://crfdesign.net/programming/top-10-differences-between-java-and-c

К сожалению, List<> не является поточно-ориентированным (C # ArrayList и Java Vector являются потокобезопасными). C # также имеет Hashtable; общая версия:

Что делает List<T> не поточно-ориентированным? Это проблема реализации со стороны инженера .NET Framework? Или дженерики не поточнобезопасны?

Ответы [ 6 ]

67 голосов
/ 01 апреля 2009

Вам действительно нужно классифицировать тип безопасности потоков Java в векторе Java. Javas Vector безопасно использовать из нескольких потоков, поскольку он использует синхронизацию методов. Государство не будет повреждено.

Однако полезность вектора Java ограничена несколькими потоками без дополнительной синхронизации. Например, рассмотрим простой акт чтения элемента из вектора

Vector vector = getVector();
if ( vector.size() > 0 ) { 
  object first = vector.get(0);
}

Этот метод не портит состояние вектора, но он также неверен. Ничто не мешает другому потоку мутировать вектор между оператором if и вызовом get (). Этот код может и будет в конечном итоге потерпеть неудачу из-за состояния гонки.

Этот тип синхронизации полезен только в некоторых сценариях и, конечно, не дешев. Вы платите заметную цену за синхронизацию, даже если вы не используете несколько потоков.

.Net решил не платить эту цену по умолчанию для сценария только ограниченной полезности. Вместо этого он решил реализовать список без блокировки. Авторы несут ответственность за добавление любой синхронизации. Это ближе к модели C ++ «плати только за то, что используешь»

Недавно я написал пару статей об опасности использования коллекций только с внутренней синхронизацией, такой как вектор Java.

Ссылка Вектор безопасности потока: http://www.ibm.com/developerworks/java/library/j-jtp09263.html

20 голосов
/ 01 апреля 2009

Почему будет поточно-ориентированным? Не каждый класс есть. Фактически, по умолчанию классы не поточно-безопасны.

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

9 голосов
/ 01 апреля 2009

Это просто проектное решение для реализации типов, не ориентированных на многопотоковое исполнение. Коллекции предоставляют свойство SyncRoot интерфейса ICollection и метод Synchronized() в некоторых коллекциях для явной синхронизации типов данных.

Используйте SyncRoot для блокировки объекта в многопоточной среде.

lock (collection.SyncRoot)
{
   DoSomething(collection);
}

Используйте collection.Synchronized(), чтобы получить потокобезопасную оболочку для коллекции.

2 голосов
/ 03 апреля 2009

Возможность состояния гонки, о которой упоминает JaredPar, является страшным следствием полагаться на предполагаемую безопасность потоков Vector. Это приводит к тому, что «каждый девятый вторник приложение делает что-то странное» - что-то вроде отчета о дефектах, который сводит вас с ума.

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

Таким образом, логичная вещь для разработчика фреймворка - поддерживать класс как можно более быстрым для 95% пользователей, которые, вероятно, не будут выполнять многопоточность, и полагаться на тех, кто делает многопоточность, чтобы знать, что им нужно сделать, чтобы сохранить его в безопасности.

2 голосов
/ 01 апреля 2009

Для истинной безопасности потоков List<> и другие типы коллекций должны быть неизменяемыми. С появлением параллельных расширений .NET в .NET 4.0 мы увидим многопоточные версии наиболее часто используемых коллекций. Джон Скит затрагивает некоторые из них.

0 голосов
/ 29 января 2010

use SynchronizedCollection также предоставляет Constructor-Parameter для использования общей синхронизации:)

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