如果对象位于另一个对象内,C# Monitor.Enter 不会锁定

rbo*_*boy -1 c# locking object

我认为只要对对象的引用或对象本身不改变,Monitor.Enter 就可以对对象的引用起作用。

这是我的简单案例,我有一个名为 QueueManager 的类,其中有一个队列。在操作队列之前,我使用此对象队列来使用 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*eet 5

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

从文档中Exit

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