深入探讨 lock
语句的内部机制
在处理非线程安全对象时,开发人员经常使用 lock
语句来保护代码执行。但是,当多个线程与这段受保护的代码交互时,底层究竟发生了什么?
深入探究:追踪 lock
语句的执行
在 C# 3.0 中,lock
语句转换为以下代码:
<code class="language-C#">var temp = obj; Monitor.Enter(temp); try { // 非线程安全代码 } finally { Monitor.Exit(temp); }</code>
在 C# 4.0 中,此过程进行了修改,生成的代码如下:
<code class="language-C#">bool lockWasTaken = false; var temp = obj; try { Monitor.Enter(temp, ref lockWasTaken); // 非线程安全代码 } finally { if (lockWasTaken) { Monitor.Exit(temp); } }</code>
Monitor.Enter
的作用
Monitor.Enter
在 lock
语句的功能中扮演着至关重要的角色。MSDN 将其操作描述如下:
“使用 Enter
获取传递为参数的对象的 Monitor
。如果另一个线程已经对该对象执行了 Enter
但尚未执行相应的 Exit
,则当前线程将阻塞,直到另一个线程释放该对象。”
从本质上讲,Monitor.Enter
保证了对对象的独占访问。如果另一个线程试图获取相同的锁,它将被挂起,直到锁被释放。同一线程多次调用 Enter
不会导致阻塞,但需要相同数量的 Exit
调用来解锁对象并允许等待的线程恢复执行。
无限等待时间
值得注意的是,Monitor.Enter
将无限期地等待锁可用。与某些锁定机制不同,它不强制执行超时时间。
以上是C#'lock”语句在幕后是如何工作的?的详细内容。更多信息请关注PHP中文网其他相关文章!