class Program
{
static object test = new object();
static void Main(string[] args)
{
new Program().test2();
Console.ReadKey();
}
public void test1()
{
lock (test)
{
Console.WriteLine("test1");
}
}
public void test2()
{
lock (test)
{
test1();
Console.WriteLine("test2");
}
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码是否应首先在test2()的lock语句中完成语句然后转到test1()?(即输出不应该是这样的吗?:test2 test1)
Jon*_*eet 15
否.事件序列(标识表示调用堆栈或逻辑操作)是:
lock语句的开头)
lock语句的开头)
lock语句结束)
lock语句结束)
重要的是要注意监视器是可重入的 - 如果当前线程已经拥有监视器,那么另一次获取它的尝试只会增加计数,而不是阻塞.
如果监视器不是可重入的,那么输出将不是"test2,test1" - 它只会是死锁.
Han*_*ant 11
监视器可以重新进入同一个线程.为避免意外死锁非常重要,如果没有这种行为,您的代码会严格冻结.
互斥体也是可重入的,信号量不是.
实施非常简单.监视器存储两条信息.输入它的线程的所有者Thread.ManagedId和计算输入次数的计数器.因此,第一个锁可以进入,因为它不是拥有的,它将所有者设置为您的线程并将计数设置为1.允许第二个锁进入,因为线程ID匹配,计数增加到2.结束时第二次锁定,计数再次减少到1.在第一个结束时,计数减少到0并重置所有者.