C#Lock语句

Mik*_* S. 9 c# mutex locking sync

当一个线程试图进入一个关键部分并获得一个锁时,它实际上在做什么?

我问这个是因为我经常创建一个对象(对象类型),它只用于锁定目的.请考虑以下内容:我想编写一个接受集合的方法,以及一个将作为锁定对象的对象,以便该方法中的整个集合操作将在临界区内声明,该区域将被该给定对象锁定.

我应该使用"ref"传递该锁定对象还是传递该对象的引用副本就足够了?换句话说 - 因为lock语句仅用于引用类型,机制是否检查引用对象的值,还是检查指针的值?因为很明显,当传递一个没有"ref"的对象时,我实际上得到了一个引用的副本,而不是引用本身.

Dav*_*ter 6

这是锁定时可以遵循的典型模式.基本上,您可以创建一个锁定对象,用于锁定对关键部分的访问(正如@Hans所说,它不保护您正在处理的对象 - 它只是处理锁定).

class ThreadSafe
{
  static readonly object _locker = new object();
  static int _val1, _val2;

  static void Go()
  {
    lock (_locker)
    {
      if (_val2 != 0) Console.WriteLine (_val1 / _val2);
      _val2 = 0;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这个例子来自Joseph Albahari关于线程的在线书籍.它提供了一个很好的概述,当你创建一个lock声明时会发生什么,以及如何最好地优化它的一些提示/技巧.绝对强烈推荐阅读.

同样,Per Albahari lock在.NET 4中将该语句转换为:

bool lockTaken = false;
try
{
  Monitor.Enter (_locker, ref lockTaken);
  // Do your stuff...
}
finally { if (lockTaken) Monitor.Exit (_locker); }
Run Code Online (Sandbox Code Playgroud)

它实际上比直接更安全Monitor.Enter然后调用Monitor.Exit你的finally,这就是它在.NET 4中添加的原因.