锁(this)和静态对象上的锁之间的区别

sen*_*ale 11 .net c# multithreading locking thread-safety

以下哪两个代码段更适合使用?

static readonly object _locker = new object();
lock (_locker)
Run Code Online (Sandbox Code Playgroud)

要么

lock (this)
Run Code Online (Sandbox Code Playgroud)

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

相关:
lock(this)和lock(thisLock)有什么区别?
为什么锁(这个){...}不好?

Ste*_*ven 20

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

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

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


Ben*_*Ben 8

锁定私有只读对象几乎总是更可取.

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

var obj = new YourClass();
lock(obj)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

......在这种情况下,内部的任何企图YourClass,以lock (this)将阻止.