MSDN上介绍Monitor时很模糊的,在Enter(obj) 的时候如果能够锁定就进入临界区,否则有其他线程已经锁定的话
只能等待,那只有放入等待队列了,拥有锁的线程在使用完后Exit(obj),他不会通知处于等待队列中的线程进入就绪队
列,但是看下面 的代码:
class MonitorSample
{
public static object obj = new object();
public static void P1()
{
Monitor.Enter(obj)
{
for (int i = 0; i < 2; ++i)
{
i++;
i--;
}
Monitor.Exit(obj);
}
Console.WriteLine("1");
}
public static void P2()
{
Monitor.Enter(obj)
{
for (int i = 0; i < 2; ++i)
{
i++;
i--;
}
Monitor.Exit(obj);
}
Console.WriteLine("2");
}
public static void P3()
{
Monitor.Enter(obj)
{
for (int i = 0; i < 2; ++i)
{
i++;
i--;
}
Monitor.Exit(obj);
}
Console.WriteLine("3");
}
static void Main(string[] args)
{
Thread th1 = new Thread(new ThreadStart(P1));
Thread th2 = new Thread(new ThreadStart(P2));
Thread th3 = new Thread(new ThreadStart(P3));
th1.Start();
th2.Start();
th3.Start();
Console.Read();
}
}
按照MSDN上的说法,在一个线程拥有obj锁的时候,这时其他线程要想访问该对象只有等待放入等待队列,那么看上面的例子,
三个线程中肯定有一个会先进入,余下两个只能等待放入等待队列,比如P1先进入,则P2,P3就放入等待队列,P1执行完后调用了
Exit(obj),但是Exit(obj)并不会通知等待队列的P2,P3到就绪队列去获取锁,也没有调用pause去通知,那么上面的P2,P3肯定要死锁,但是
结果却不是死锁,不知原因是什么?希望高手解疑s
2011.5.09
最近在使用的时候发现,调用enter(obj)会进入就绪对列,等待获取锁,Exit(obj)之后,就绪队列中的第一个线程会获取该锁,但是Exit(obj)不会通知在等待队列中的
线程进入就绪对列。
class MonitorSample
{
public static object obj = new object();
public static void P1()
{
Console.WriteLine(" b enter 1");
Monitor.Enter(obj);
Console.WriteLine("enter 1");
Console.WriteLine("P1 "+Thread.CurrentThread.GetHashCode());
Monitor.Wait(obj);
Console.WriteLine("P1 "+Thread.CurrentThread.GetHashCode());
Monitor.PulseAll(obj);
Monitor.Exit(obj);
}
public static void P2()
{
Console.WriteLine(" b enter 2");
Monitor.Enter(obj);
Console.WriteLine("enter 2");
Console.WriteLine("P2 "+Thread.CurrentThread.GetHashCode());
Monitor.Wait(obj);
Console.WriteLine("P2 "+Thread.CurrentThread.GetHashCode());
Monitor.PulseAll(obj);
Monitor.Exit(obj);
}
public static void P3()
{
Console.WriteLine(" b enter 3");
Monitor.Enter(obj);
Console.WriteLine("enter 3");
Console.WriteLine("P3 " + Thread.CurrentThread.GetHashCode());
Monitor.PulseAll(obj);
Monitor.Wait(obj);
Console.WriteLine("P3 " + Thread.CurrentThread.GetHashCode());
Monitor.Exit(obj);
}
static void Main(string[] args)
{
Thread th1 = new Thread(new ThreadStart(P1));
Thread th2 = new Thread(new ThreadStart(P2));
Thread th3 = new Thread(new ThreadStart(P3));
th1.Start();
th2.Start();
th3.Start();
Console.Read();
}
}