Является ли объект SyncRoot действительно потокобезопасным? - PullRequest
3 голосов
/ 06 января 2012

Я новичок в концепции SyncRoot. Насколько я могу судить, объект, используемый для блокировки, должен быть закрытым.

Однако HashTable имеет открытое свойство SyncRoot, которое является просто оболочкой над закрытым объектом SyncRoot. рекомендуется , чтобы заблокировать HashTable.SyncRoot при перечислении коллекции.

Кажется, что мы можем потерпеть неудачу с помощью мертвой блокировки, поскольку она больше не является закрытой. Это действительно потокобезопасный?

Что если я сделаю свой собственный закрытый механизм блокировки? private readonly object _syncObject;

Какой из них лучше и почему?

Ответы [ 2 ]

7 голосов
/ 06 января 2012

Нет, это не реальная проблема с подходом .NET 1.x. Свойство является общедоступным, поскольку оно имеет для публичного доступа. Проблема в том, чтобы перечислить коллекцию. Нет никакого способа реализовать это потокобезопасным способом, нет механизма автоматической блокировки, когда вы начинаете перечислять, и разблокировать, когда вы закончите. IEnumerable не имеет метода Completed и не наследует IDisposable.

Таким образом, чтобы код мог безопасно перечисляться, вам нужен доступ к объекту блокировки. Таким образом, вы можете обернуть оператор foreach блокировкой этого объекта. Таким образом, публичное свойство SyncRoot.

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

5 голосов
/ 06 января 2012

ICollection.SyncRoot только для предварительных коллекций. Это в основном устарело.

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

...