为了避免死锁,我阅读了一些关于SyncRoot模式的一般规则。阅读几年前的一个问题(请参阅这个链接),我想我理解这种模式的某些用法可能是不正确的。特别是,我集中讨论了本题中的下列句子:
您将注意到SyncRoot属性在System.Collections中的许多集合上。回顾一下,我认为这个财产是个错误..。请放心,在构建这些集合的通用版本时,我们不会犯同样的错误。
实际上,例如,List<T>类没有实现SyncRoot属性,或者更正确地说,它是显式实现的(参见这个答案),因此您必须转换为ICollection才能使用它。但这句话认为,公开私有SyncRoot字段与锁定this (参见这个答案)一样糟糕,这一点在这句话中也得到了证实。
因此,如果我正确理解,当我实现一个非线程安全的数据结构时,由于它可以在多线程上下文中使用,我不应该(实际上,我不能)提供SyncRoot属性。但是,我应该让开发人员(将使用此数据结构)承担将其与私有SyncRoot对象关联的任务,如下面的示例代码所示。
public class A
{
private MyNonThreadSafeDataStructure list;
private readonly object list_SyncRoot = new object;
public Method1()
{
lock(list_SyncRoot)
{
// access to "list" private field
}
}
public Method2()
{
lock(list_SyncRoot)
{
// access to "list" private field
}
}
}总之,我理解同步/锁定的最佳实践应该如下:
SyncRoot属性(也请参见这句话)。上面写的是这个模式的正确用法吗?
发布于 2012-09-14 13:52:49
我将避免将SyncRoot属性添加到我设计的类型中,原因如下:
Mutex、ReaderWriterLock或ReaderWriterLockSlim等。this或typeof(MyClass)),即这是错误的:
公共对象SyncRoot {get {返回此;}我还将避免从SyncRoot框架类型中使用.NET属性。如果我需要创建一个w/o SyncRoot属性线程安全类型,我将使用一个锁定模式,如果一个类型具有此属性,我仍然不会选择锁定SyncRoot。这使我的代码风格一致,易于阅读/维护。
发布于 2012-09-14 13:33:31
这里有许多概念。首先,正确实现的是一个线程安全类,该类的使用者不需要自己进行同步。因此,绝对不需要公开syncRoot对象。在旧集合类中,由于类不是线程安全的,所以公开了SyncRoot属性。
在锁定任意对象并锁定内部集合时,程序的正确性或性能绝对没有差别。只要对两者的引用没有改变,它们的工作原理就像参数一样适用于Monitor.Enter/Exit。你的内心收藏会改变吗?如果没有,也把它标记为只读。
第三,对基于不同操作的不同锁的使用提出了意见。典型的例子是ReaderWriterLock。您应该根据类公开的不同功能来分析使用不同级别锁的需要。
https://stackoverflow.com/questions/12424993
复制相似问题