C# Monitor与线程同步
Monitor对象(C#知识点总结系列:4、C#中Monitor和Lock以及区别)
1.Monitor.Enter(object)方法是获取锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的两个方法,当然在使用过程中为了避免获取锁之后因为异常,致锁无法释放,所以需要在try{} catch(){}之后的finally{}结构体中释放锁(Monitor.Exit())。
2.Monitor的常用属性和方法:
Enter(Object) 在指定对象上获取排他锁。
Exit(Object) 释放指定对象上的排他锁。
IsEntered 确定当前线程是否保留指定对象锁。
Pulse 通知等待队列中的线程锁定对象状态的更改。
PulseAll 通知所有的等待线程对象状态的更改。
TryEnter(Object) 试图获取指定对象的排他锁。
TryEnter(Object, Boolean) 尝试获取指定对象上的排他锁,并自动设置一个值,指示是否得到了该锁。
Wait(Object) 释放对象上的锁并阻止当前线程,直到它重新获取该锁。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; //线程同步与多线程程序中的隐患 namespace Multithreading_hazard { class Program { private static int stickets = 100; static object gloalObj=new object();//辅助对象 static void Main(string[] args) { Thread thread1 = new Thread(SaleTicketThread1); Thread thread2 = new Thread(SaleTicketThread2); thread1.Start(); thread2.Start(); Thread.Sleep(4000); } private static void SaleTicketThread1() { while (true) { try { Monitor.Enter(gloalObj);//在gloalObj对象上获得排他锁 Thread.Sleep(1); if (stickets > 0) { Console.WriteLine("线程一出票{0}:", stickets--); } else { break; } } finally { Monitor.Exit(gloalObj);//释放指定对象上的排他锁 } } } private static void SaleTicketThread2() { while (true) { try { Monitor.Enter(gloalObj);//在gloalObj对象上获得排他锁 Thread.Sleep(1); if (stickets > 0) { Console.WriteLine("线程二出票{0}:", stickets--); } else { break; } } finally { Monitor.Exit(gloalObj);//释放指定对象上的排他锁 } } } } }
利用Monitor的Enter(Object) 、Exit(Object)实现了线程同步,一个线程将等待前一个线程执行完成后,才继续执行