我认为只要对对象或对象本身的引用没有改变,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 !!我无法理解为什么它不会死锁。我试过这个是因为我怀疑锁被拿走所以我把这个测试代码放进去了,我很惊讶。
答案 0 :(得分:3)
监视器重入 - 一个线程可以多次拥有一个监视器。当Exit
被调用的次数与Enter
相同时,监视器仅解锁(可供另一个线程获取)。
来自Exit
的文档:
调用线程必须拥有obj参数的锁。如果调用线程拥有对指定对象的锁定,并且对该对象进行了相同数量的Exit和Enter调用,则释放锁定。如果调用线程没有像Enter那样多次调用Exit,则不会释放锁定。
答案 1 :(得分:1)
这不是DEADLOCK !!
这是因为对Enter()
的两次调用都来自同一个线程。监视器是递归可重入的。