【发布时间】:2011-03-19 09:33:12
【问题描述】:
object theLock = new object();
...
lock (theLock)
{
...
}
我总是为此使用new object(),但我想知道:在任何情况下您会锁定更具体的类型吗?
【问题讨论】:
标签: c# .net locking parallel-processing
object theLock = new object();
...
lock (theLock)
{
...
}
我总是为此使用new object(),但我想知道:在任何情况下您会锁定更具体的类型吗?
【问题讨论】:
标签: c# .net locking parallel-processing
在我看来,任何引用类型都可以被锁定,使用虚拟对象的原因是为了避免常见的锁定陷阱:
常见的构造锁(this), lock (typeof (MyType)) 和 lock ("myLock") 违反此准则:
lock (this) is a problem if the instance can be accessed publicly. lock (typeof (MyType)) is a problem if MyType is publicly可访问。
lock("myLock") is a problem because any other code in the process使用相同的字符串,将共享 同一个锁。
【讨论】:
如果是new,Type 无关紧要,实例可以。在这种情况下,您说的是 synclock 对象:用于锁定代码部分以防止并发访问的对象。
使用另一个Type 而不是object 作为同步锁会浪费内存,因为您不会将此实例用于其他任何事情。
在某些情况下,您可以锁定另一种类型:当您需要锁定特定实例时。 主要问题是:必须初始化实例才能锁定它。而且在大多数情况下,您希望同步实例的初始化:)
但在某些情况下,您可以直接锁定实例;例如像字典一样(在这种情况下几乎是直接的;))。
private Dictionary<string,string> _dictionary = new Dictionary<string,string>();
public void AddValue(string key, string value)
{
lock (((IDictionary)_dictionary).SyncRoot) // SyncRoot recommended
{
if (!_dictionary.ContainsValue(value))
_dictionary.Add(key, value);
}
}
但重点是:即使这可行,也要始终问自己:“创建一个特定的锁定对象不是更好的主意吗?”
【讨论】:
SyncRoot 属性。
我很确定你知道那篇文章 Lock Statement (C# Reference)。
一般来说,避免锁定 public 类型或超出代码控制范围的实例。常见的构造lock(this)、lock(typeof(MyType))和lock("myLock")违反了这个准则:
最佳做法是定义一个 private 对象来锁定,或者定义一个 private static 对象变量来保护所有实例共有的数据。
【讨论】: