有没有理由锁定除new object()之外的东西?

Ily*_*gan 5 .net c# parallel-processing locking

object theLock = new object();

...


lock (theLock)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

我总是使用a new object(),但我想知道:在任何情况下你会锁定更具体的类型吗?

Cap*_*mic 5

在我看来,任何引用类型都可以被锁定,使用虚拟对象的原因是为了避免常见的锁定陷阱:

常见的构造锁(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
Run Code Online (Sandbox Code Playgroud)

无障碍.

  lock("myLock") is a problem because any other code in the process
Run Code Online (Sandbox Code Playgroud)

使用相同的字符串,将共享相同的锁.


Joe*_*lly 4

如果是 a new,则Type并不重要,实例才重要。在本例中,您讨论的是同步锁对象:用于锁定代码部分以防止并发访问的对象。

使用另一个同步锁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);
    }
}
Run Code Online (Sandbox Code Playgroud)

但重点是:即使这可行,也要始终问自己:“创建一个特定的锁定对象不是一个更好的主意吗”?