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

本文关键字:释放 是否 语句 锁定 | 更新日期: 2023-09-27 18:34:18

我最近读了 Eric Lippert 关于 c# 中锁实现的这篇文章,但仍然存在一些问题。

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

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

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

在 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 块中运行,因此不可中止。

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

不。线程中止将延迟,直到控制离开 final。解锁有效锁不会分配内存或引发其他异常。

阅读有关ThreadAbortException

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

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

所以是的,锁仍然会被释放。不过,这是否可取是另一回事 - 您不知道线程即将释放锁 - 它可能在任何地方,并且可能正在改变锁所保护的状态 - 所以一如既往,建议是避免Thread.Abort