Enter, TryEnter
获取对象锁。此操作同样会标记临界区的开头。其他任何线程都不能进入临界区,除非它使用其他锁定对象执行临界区中的指令。
Wait
释放对象上的锁以便允许其他线程锁定和访问该对象。在其他线程访问对象时,调用线程将等待。脉冲信号用于通知等待线程有关对象状态的更改。
Pulse (信号), PulseAll
向一个或多个等待线程发送信号。该信号通知等待线程锁定对象的状态已更改,并且锁的所有者准备释放该锁。等待线程被放置在对象的就绪队列中以便它可以最后接收对象锁。一旦线程拥有了锁,它就可以检查对象的新状态以查看是否达到所需状态。
Exit
释放对象上的锁。此操作还标记受锁定对象保护的临界区的结尾。
public void DoCriticalSection()
{
Monitor.Enter(this.lockMe);
Console.WriteLine(string.Format("DoCriticalSection lock held by ThreadID:{0} ", Thread.CurrentThread.ManagedThreadId));
for (int i = 0; i < 5; i++)
{
Monitor.Pulse(this.lockMe);
Console.WriteLine(string.Format("Thread ID:{0} Pulse", Thread.CurrentThread.ManagedThreadId));
Console.WriteLine(string.Format("MonitorWaitAndPulse1 Result:{0}", result++));
Thread.Sleep(1000);
Monitor.Wait(this.lockMe);
Console.WriteLine(string.Format("Thread ID:{0} Wait", Thread.CurrentThread.ManagedThreadId));
}
Console.WriteLine(string.Format("DoCriticalSection lock realease by ThreadID:{0} ", Thread.CurrentThread.ManagedThreadId));
Monitor.Exit(this.lockMe);
}
public void DoCriticalSection()
{
Monitor.Enter(this.lockMe);
Console.WriteLine(string.Format("DoCriticalSection lock held by ThreadID:{0} ", Thread.CurrentThread.ManagedThreadId));
for (int i = 0; i < 5; i++)
{
//Monitor.Pulse(this.lockMe);
Console.WriteLine(string.Format("Thread ID:{0} Pulse", Thread.CurrentThread.ManagedThreadId));
Console.WriteLine(string.Format("MonitorWaitAndPulse1 Result:{0}", result++));
Thread.Sleep(1000);
//Monitor.Wait(this.lockMe);
Console.WriteLine(string.Format("Thread ID:{0} Wait", Thread.CurrentThread.ManagedThreadId));
}
Console.WriteLine(string.Format("DoCriticalSection lock realease by ThreadID:{0} ", Thread.CurrentThread.ManagedThreadId));
Monitor.Exit(this.lockMe);
}
使用Monitor.Wait与Monitor.Pulse可以上线程交替执行,如果只使用Enter与Exit,当代码进入Monitor.Enter临界区后,当前线程不Monitor.Exit,其他线程只能等待. Monitor.Pulse之后下一线程就可以得到锁并执行。Monitor.Wait之后等待其他线程释放锁。