传递给lock关键字的内容是什么?

时间:2010-02-23 15:26:30

标签: c# .net locking

使用

之间有什么区别(如果有的话)
void MethodName()
{
    lock(this)
    {
        // (...)
    }
}

private object o = new object();
void MethodName()
{
    lock(o)
    {
        // (...)
    }
}

性能有差异吗?样式?行为?

4 个答案:

答案 0 :(得分:17)

lock(this)将锁定“当前”对象。

锁定“this”通常是一个坏主意,因为它将锁暴露给其他代码;我更喜欢有一个只读字段,如下所示:

public class Foo
{
    private readonly object padlock = new object();

    public void SomeMethod()
    {
        lock(padlock)
        {
            ...
        }
    }
}

这样所有对SomeMethod的调用(以及Foo中锁定padlock的任何其他内容)将锁定同一个Foo实例的监视器,但是锁定该显示器无其他任何干扰。

实际上,除非你正在处理“流氓”代码,否则其他代码 实际上不会锁定对Foo实例的引用,但这是一个问题封装

答案 1 :(得分:11)

不同之处在于任何人都可以锁定您的实例,但只有您可以锁定私有对象。

这有助于防止死锁。

例如:

假设Microsoft在lock(this)类中使用了Control

然后,如果其他人锁定了Control实例,他的锁会阻止Control中的代码运行,这不是他想要的。

如果你lock on types that are shared across AppDomains

,这一点尤其糟糕

答案 2 :(得分:3)

对于声明为static ....

的类,我通常遵循的模式是这样的
public static class SomeClass{
    private static object objLock = new object();
    ....
    public static object SomeProperty{
       get{ 
           lock(objLock){
             // Do whatever needs to be done
           }
       }
       set{
           lock(objLock){
           }
       }
    }
}

同样对于正常的课程,我会遵循这种模式:

public class SomeClass{
    private readonly object objLock = new object();
    ....
    public object SomeProperty{
       get{ 
           lock(objLock){
             // Do whatever needs to be done
           }
       }
       set{
           lock(objLock){
           }
       }
    }
}

通过这种方式,没有人可以锁定我的实例并防止发生死锁......

编辑:我修改了这篇文章,以便更清楚地了解将使用static锁的基础的代码以及正常的类...谢谢<强烈的> 史蒂文 Dalle 因为他们的观点......

答案 3 :(得分:1)

范围存在差异,行为可能存在差异 (顺便说一句,MS不建议使用“this”


// in this case, your lock object is public, so classes outside of this can lock on the same thing
lock(this) {}

// in this case, your lock is private, and only you can issue a lock statement against it
private object lockobj = new object()
..
lock(this.lockobj) {}

// this one is WRONG -- you willget a new object instance every time, so your lock will not provide mutual exclusion
void SomeMethod()
{
  // using a local variable for a lock -- wrong
  object obj = new object();
  lock(obj) {}
}