当您查看C#的Monitor
类(lock
关键字下面的类时,您会发现在其实现中您有一个条件变量和一个互斥锁。通过新线程进入获取互斥锁,如果尚未被另一个线程获取,则继续检查条件变量,如果是true
,则线程可以继续,如果不是,则然后它被置于条件变量的线程休眠队列中,以便在条件变量再次变为真时被唤醒。
现在,为什么Monitor
需要条件变量?它检查什么条件?我已阅读有关Monitor的wikipedia's文章,但我无法推断它会等待的条件是什么?
它不是由lock
或Monitor
的用户指定的内容,而是一些内部变量。通过锁定看object
作为参数,supposedly only for identifying锁定。
这就像使用AutoResetEvent
和Mutex
并获取互斥锁上的锁定,然后查看AutoResetEvent
是否设置为已发出信号?
我不确定为什么Monitor
需要一个条件变量,当一个线程等待获取一个互斥锁时,它是否也会在互斥体被释放时被唤醒? (OS调度程序可能是唤醒的那个)
我希望这是有道理的,而且有人可以在我的理解中找到差距。
答案 0 :(得分:0)
这是CLR 4.0中引入的Monitor.Enter方法的重载,用于纠正一个微妙的漏洞。
this website中对此进行了解释。
Monitor.Enter (_locker);
try
{
if (_val2 != 0) Console.WriteLine (_val1 / _val2);
_val2 = 0;
}
finally { Monitor.Exit (_locker); }
考虑在Monitor.Enter的实现中抛出异常的(不太可能的)事件,或者在Monitor.Enter和try块的调用之间(可能是由于在该线程上调用Abort或者OutOfMemoryException)被抛出)。在这种情况下,可能会或可能不会采取锁定。如果锁定,它将不会被释放 - 因为我们永远不会进入try / finally块。这将导致泄漏锁定。
为了避免这种危险,CLR 4.0的设计人员将以下重载添加到Monitor.Enter