首页 文章

锁定语句 - 是否始终释放锁定?

提问于
浏览
6

我最近阅读了this post from Eric Lippert regarding the lock implementation in c#,但仍然存在一些问题 .

在4.0实现中,如果在执行finally块中的Monitor.Exit(temp)之前发生了线程中止或任何跨线程异常 - 是否会保持对象的锁定?

是否有可能在此级别发生异常,使对象仍处于锁定状态?

2 回答

  • 9

    在4.0实现中,如果在执行finally块中的Monitor.Exit(temp)之前发生线程中止或任何交叉线程异常 - 是否会保持对对象的锁定?

    让我们来看看那段代码,以便其他读者清楚:

    bool lockWasTaken = false;
    var temp = obj;
    try 
    { 
      Monitor.Enter(temp, ref lockWasTaken); 
      { 
        body 
      } 
    }
    finally 
    { 
      if (lockWasTaken) 
      {
        // What if a thread abort happens right here?
        Monitor.Exit(temp); 
      }
    }
    

    你的问题是不可回答的,因为它是基于一个错误的假设,即线程中止可能发生在finally块的中间 .

    线程中止不能发生在finally块的中间 . 这只是为什么你永远不应该试图中止一个线程的原因之一 . 整个线程可以在finally块中运行,因此不可中止 .

    是否有可能在此级别发生异常,使对象仍处于锁定状态?

    不会 . 线程中止将被延迟,直到控制离开最终 . 解锁有效锁不会分配内存或抛出另一个异常 .

  • 14

    阅读ThreadAbortException

    引发此异常时,运行时会在结束线程之前执行所有finally块

    (这包括调用 Thread.Abort 时当前正在执行的任何 finally 块)

    所以,是的,锁定将被释放 . 这是否可取是一个非常不同的问题 - 你不知道线程即将释放锁 - 它可能在任何地方,并且可能正在改变锁保护的状态 - 一如既往,建议是避免 Thread.Abort .

相关问题