C#Monitor。如果Object位于另一个Object中,则输入不锁定

时间:2013-04-30 19:34:24

标签: c# object locking

我认为只要对对象或对象本身的引用没有改变,Monitor.Enter就可以对对象进行引用。

所以这是我的简单案例,我有一个名为QueueManager的类,里面有一个Queue。我正在使用此对象队列在操作队列之前使用Monitor.Lock进行锁定。我尝试了在队列对象上调用Monitor.Lock的简单测试,但它失败了。知道为什么吗?

public class QueueManager
{
    private List<ConversionJob> _jobQueue = new List<ConversionJob>();

    public QueueManager()
    {
    }

    public List<ConversionJob> Queue
    { get { return _jobQueue; } }
}

public class Main
{
    private QueueManager qMgr = new QueueManager();

    public Main()
    {
        try
        {
            Monitor.Enter(qMgr.Queue);
            throw new Exception();
        }
        catch (Exception)
        {
            Monitor.Enter(qMgr.Queue);
        }
    }
}

这不是DEADLOCK !!我无法理解为什么它不会死锁。我试过这个是因为我怀疑锁被拿走所以我把这个测试代码放进去了,我很惊讶。

2 个答案:

答案 0 :(得分:3)

监视器重入 - 一个线程可以多次拥有一个监视器。当Exit被调用的次数与Enter相同时,监视器仅解锁(可供另一个线程获取)。

来自Exit的文档:

  

调用线程必须拥有obj参数的锁。如果调用线程拥有对指定对象的锁定,并且对该对象进行了相同数量的Exit和Enter调用,则释放锁定。如果调用线程没有像Enter那样多次调用Exit,则不会释放锁定。

答案 1 :(得分:1)

  

这不是DEADLOCK !!

这是因为对Enter()的两次调用都来自同一个线程。监视器是递归可重入的。