Обновление - в .NET 4 теперь есть ConcurrentQueue<T>
в System.Collections.Concurrent, как описано здесь http://msdn.microsoft.com/en-us/library/dd267265.aspx. Интересно отметить, что его метод IsSynchronized (справедливо) возвращает ложь.
ConcurrentQueue<T>
- это полное перезапись с нуля, создание копий очереди для перечисления и использование передовых методов без блокировки, таких как Interlocked.CompareExchange()
и Thread.SpinWait()
.
Остальная часть этого ответа по-прежнему актуальна, поскольку она связана с гибелью старых членов Synchronize () и SyncRoot и почему они не очень хорошо работают с точки зрения API.
Согласно комментарию Zooba, команда BCL решила, что слишком много разработчиков неправильно понимают цель Synchronize (и в меньшей степени SyncRoot)
Брайан Грюкмейер описал это в блоге команды BCL пару лет назад:
http://blogs.msdn.com/bclteam/archive/2005/03/15/396399.aspx
Ключевой проблемой является получение правильной детализации вокруг блокировок, когда некоторые разработчики наивно используют несколько свойств или методов в «синхронизированной» коллекции и полагают, что их код является поточно-ориентированным. Брайан использует Queue в качестве своего примера,
if (queue.Count > 0) {
object obj = null;
try {
obj = queue.Dequeue();
Разработчики не осознают, что Count может быть изменен другим потоком до вызова Dequeue.
Принудительное использование разработчиками явного оператора блокировки для всей операции означает предотвращение этого ложного чувства безопасности.
Как упоминает Брайан, удаление SyncRoot было отчасти потому, что он был в основном введен для поддержки Synchronized, а также потому, что во многих случаях лучше выбирать объект блокировки - в большинстве случаев, либо сам экземпляр Queue, либо
private static object lockObjForQueueOperations = new object();
в классе, владеющем экземпляром очереди ...
Этот последний подход обычно наиболее безопасен, поскольку позволяет избежать некоторых других распространенных ловушек:
Как говорится, многопоточность трудна , и упрощать ее может быть опасно.