【问题标题】:Difference between lock(this) and a lock on static objectlock(this) 和静态对象上的锁的区别
【发布时间】:2015-03-25 09:04:30
【问题描述】:

以下两个代码sn-ps哪个好用?

static readonly object _locker = new object();
lock (_locker)

lock (this)

this 是当前实例的对象。那么为什么lock (_locker) 总是在书中呢?

相关:
What is the difference between lock(this) and lock(thisLock)?
Why is lock(this) {…} bad?

【问题讨论】:

    标签: c# .net multithreading locking thread-safety


    【解决方案1】:

    可能会有很大的不同。两者之间最大的区别是第一个示例使用单个对象锁定(因此static 关键字),而第二个示例中的this 关键字意味着锁定一个实例。因此,从性能的角度,甚至从正确性的角度来看,可能会有很大的不同,但这取决于锁内的代码。

    如果您只需要同步对实例级字段的访问,则不应使用 static 关键字,因为这将同步代码本身,而不是数据(这可能会导致不必要的性能损失)。当然,如果数据本身是静态的(类级数据而不是实例级数据),则需要使用static关键字。另一方面,当您使用this 关键字锁定时,当您访问共享/静态资源时,您(当然)会遇到正确性问题,因为同步是基于实例的,并且多个实例仍然是能够同时访问共享数据。

    还有另一个问题,但与前面提到的差异相比,差异要小得多。第一个示例使用一个私有声明的对象来锁定,而另一个使用this 指针,这是对该实例方法本身的对象的引用。由于其他对象可以公开访问此引用,因此它们可能会锁定它,这在极少数情况下可能会导致死锁。如果您是应用程序开发人员,我不会太担心这一点(只要您不锁定 System.StringSystem.Type 之类的东西),但如果您是框架开发人员,您当然不应该使用lock(this),因为没有办法知道应用程序开发人员将以何种方式(ab)使用您的代码。

    【讨论】:

    • Steven,关于“...将同步代码本身,而不是数据(这可能会导致不必要的性能损失)”——您能否详细说明为什么这会影响性能? TIA
    【解决方案2】:

    几乎总是最好锁定私有只读对象。

    不同之处在于this通常对外部代码可见,这可能会对其进行锁定,即-

    var obj = new YourClass();
    lock(obj)
    {
        ...
    }
    

    ...在这种情况下,YourClass 内部对lock (this) 的任何尝试都会被阻止。

    【讨论】:

      【解决方案3】:

      因为您不希望从对象外部访问锁。

      如果你使用 lock(this) 你会遇到死锁:

      void blah() {
         lock(this);
         sleep(200);
      }
      
      //Some other block of code
      
      MyObject a;
      foreach(Mythread m in threads)
      {
         lock(a);
         m.Call(a.blah); //Not the best syntax, but you get the idea.
      }
      

      如果你将锁保持在对象内部,它就不会死锁。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-07
        相关资源
        最近更新 更多