-1

我认为 Monitor.Enter 对对象的引用起作用,只要对对象的引用或对象本身没有改变。

所以这是我的简单案例,我有一个名为 QueueManager 的类,其中有一个 Queue。在操作队列之前,我正在使用此对象 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);
        }
    }
}

这不是死锁!!我不明白为什么它不会死锁。我尝试了这个,因为我怀疑锁被占用了,所以我把这个测试代码放进去,我很惊讶。

4

2 回答 2

4

监视器是可重入的——一个线程可以多次拥有一个监视器。监视器只有在Exit被调用的次数与Enter.

从文档中Exit

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

于 2013-04-30T19:36:39.577 回答
1

这不是死锁!!

那是因为这两个调用Enter()都是从同一个线程进行的。监视器是递归可重入的。

于 2013-04-30T19:36:41.030 回答