锁定某事

时间:2014-08-05 10:01:18

标签: c# multithreading concurrency thread-safety

我对同步化了解得足够多,并在一些项目中使用过它。但是,尽管如此,我仍然不能理解锁定 ON 的意义。以C#为例:

class Class1{
  private static readonly object locker = new object();
  void Method1(){
    lock(locker) { .... }
  }
}

这里我们锁定了更衣室对象。但是,如果我们锁定其他内容会怎么样:

//1
class Class1{
  void Method1(){
    lock("123") { .... }
  }
}

//2
class Class1{
  void Method1(){
    lock(123) { .... }
  }
}

//3
class Class1{
  void Method1(){
    lock(new object()) { .... }
  }
}

//4
class Class1{
  void Method1(){
    lock(this) { .... }
  }
}

会有什么变化?而且,再一次,锁定" ON"什么?

P.S。我搜索了答案,没有重复的问题!

3 个答案:

答案 0 :(得分:3)

lock语句基本上转换为类似的内容:

System.Threading.Monitor.Enter(x);
try { ... }
finally { System.Threading.Monitor.Exit(x); }

Monitor.EnterMonitor.Exit方法采用object(引用类型),每个object内部都是Win32 CRITICAL_SECTION,这是一个内部领域。该关键部分是通过调用Win32 API锁定的部分。

这就是为什么锁定值类型是一个非常糟糕的主意,因为该类型被装箱并且对盒装值进行锁定,这在每次装箱时都是不同的。因此,通过锁定值类型,您实际上根本不会锁定。

因此锁定某些东西,实质上意味着以某种方式将某些内容标记为已锁定并能够以线程安全的方式检查它是否已锁定。此外,只有锁定对象的实体才能解锁它。

答案 1 :(得分:2)

你锁定的东西并不重要。 lock只关心其参数的对象标识,而不关心该对象在语义上的含义。

简单规则是:同一对象引用上只能锁定一个锁定区域,可以同时运行。用于锁定的不同对象引用不会相互干扰。

创建一个约定,确保应该互斥的代码使用相同的对象引用来锁定。并不重要的是它是什么对象。 object类型的对象很好(只要每次都是object - 所以你必须在某处存储对该对象的引用,并且每次都传递相同的引用。)

一个测验问题:你的4个选择中哪一个没有意义?

答案 2 :(得分:1)

将锁定的对象视为任何线程可以获取的项目。

一旦线程抓住它(=输入" lock(){}"代码块),该项目将无法供其他人使用,直到它被释放(=线程)持有它已退出" lock(){}"代码块)。

如果线程B试图抓住被锁定的对象,而另一个线程A仍然持有它,则B必须耐心等待直到A释放它。