【问题标题】:Is there any reason to lock on something other than new object()?除了新对象()之外,还有什么理由锁定其他东西吗?
【发布时间】:2011-03-19 09:33:12
【问题描述】:
object theLock = new object();

...


lock (theLock)
{
    ...
}

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

【问题讨论】:

    标签: c# .net locking parallel-processing


    【解决方案1】:

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

    常见的构造锁(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
    

    使用相同的字符串,将共享 同一个锁。

    【讨论】:

      【解决方案2】:

      如果是newType 无关紧要,实例可以。在这种情况下,您说的是 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 属性。
      【解决方案3】:

      我很确定你知道那篇文章 Lock Statement (C# Reference)

      一般来说,避免锁定 public 类型或超出代码控制范围的实例。常见的构造lock(this)、lock(typeof(MyType))lock("myLock")违反了这个准则:

      • lock (this) 如果 实例可以公开访问。
      • lock(typeof(MyType)) 是个问题 如果 MyType 可公开访问。
      • lock(“myLock”) 是一个问题,因为任何 过程中的其他代码使用 相同的字符串,将共享相同的 锁。

      最佳做法是定义一个 private 对象来锁定,或者定义一个 private static 对象变量来保护所有实例共有的数据。

      【讨论】:

        猜你喜欢
        • 2011-06-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-15
        • 1970-01-01
        • 2015-12-08
        • 1970-01-01
        相关资源
        最近更新 更多