What is the difference (if any) between using
void MethodName()
{
lock(this)
{
// (...)
}
}
或者
private object o = new object();
void MethodName()
{
lock(o)
{
// (...)
}
}
性能、样式、行为有区别吗?
lock(this)
会锁定“当前”对象。
在“this”上加锁通常是不好的做法,因为它会将锁暴露给其他代码;我更喜欢使用只读字段,像这样:
public class Foo
{
private readonly object padlock = new object();
public void SomeMethod()
{
lock(padlock)
{
...
}
}
}
这样一来,所有对SomeMethod
的调用(以及Foo
中任何其他在padlock
上锁定的内容)都将在同一个监视器上为Foo
的同一个实例进行锁定,但其他任何东西都不能通过锁定该监视器干扰。
实际上,除非你正在处理“流氓”代码,否则很少有其他代码会实际锁定Foo
实例的引用,但这是封装的问题。
区别在于任何人都可以锁定您的实例,但只有您可以锁定私有对象。
这有助于防止死锁。
例如:
假设Microsoft在Control
类中使用了lock(this)
。
然后,如果其他人锁定了一个Control
实例,他的锁将防止Control
中的代码运行,这不是他想要的。
如果您在跨AppDomains共享的类型上进行锁定,那么情况就会变得特别糟糕。
static
的类...
public static class SomeClass{ private static object objLock = new object(); .... public static object SomeProperty{ get{ lock(objLock){ // 做必要的事情 } } set{ lock(objLock){ } } } }
对于普通类,我会遵循这个模式:
public class SomeClass{ private readonly object objLock = new object(); .... public object SomeProperty{ get{ lock(objLock){ // 做必要的事情 } } set{ lock(objLock){ } } } }
通过这种方式,没有人能够锁定我的实例,并且可以防止死锁的发生...
编辑: 我已经修改了这篇文章,以使代码更明确,其中基础是使用static
锁和普通类... 感谢Steven和Dalle的指出...
static
锁吗? - dalle作用域有所不同,行为也可能有所不同(顺便提一下,MS不建议使用“this”)
// 在这种情况下,您的锁对象是公共的,因此在外部类中可以锁定相同的内容
lock(this) {}
// 在这种情况下,您的锁是私有的,只有您才能对其发出锁定语句
private object lockobj = new object()
..
lock(this.lockobj) {}
// 这个是错误的--每次都会得到一个新的对象实例,因此您的锁将无法提供互斥
void SomeMethod()
{
// 使用本地变量进行锁定--错误
object obj = new object();
lock(obj) {}
}