锁在里面

本文关键字:在里面 | 更新日期: 2023-09-27 18:23:40

我想知道这个构造是否会导致错误:

lock(sync)
{
  // something
  lock(sync)
  {
    //something
    lock(sync)
    {
      //something
    }
  }
}

我已经运行了这段代码,看起来很好,但在某些情况下可能会引发错误?

锁在里面

lockMonitor.EnterMonitor.Exit:的包装器

lock关键字在块的开头调用Enter,在块的末尾调用Exit。来自前者的文件:

来自Monitor.Enter:的文档

同一线程多次调用Enter而不阻塞它是合法的;但是,在等待该对象的其他线程解除阻止之前,必须调用相同数量的Exit调用。

因为对EnterExit的调用是成对的,所以您的代码模式具有定义良好的行为。

然而,请注意,lock不能保证是一个无异常的构造:

如果Interrupt中断了等待进入lock语句的线程,则抛出ThreadInterruptedException

要解释为什么它是定义良好的行为并且永远不会失败:

旁白:这个答案有关于锁如何实际工作的更好的细节

锁发生在Thread级别,因此在同一线程上再次调用它将是多余的。我认为它不会有任何性能损失(尽管这取决于.Net内部的编写方式,所以我不能保证)

很多时候,您会有一个公共函数调用类中的另一个公共功能,当单独使用时,这两个函数都需要锁。如果不允许,以下操作将失败:

private Dictionary<string, int> database = new Dictionary<string, int>();
private object databaseLock = new object();
public void AddOrUpdate(string item)
{
    lock (databaseLock)
    {
        if (Exists(item))
            database.Add(item, 1);
        else
            ++database[item];
    }
}
public bool Exists(string item)
{
    lock (databaseLock)
    {
        //... Maybe some pre-processing of the key or item...
        return database.ContainsKey(item);
    }
}

根据MSDN(请参阅此处和此处),这是定义良好的行为,不会造成任何问题。