一 概述
在C#中Monitor类的命名空间是System.Threading,它的用法比lock的用法要复杂一些,但本质是一样的
二 语法形式
1 2 3 4 5 6 7 8 9
| Monitor.Enter(object); try { //临界区代码 } finally { Monitor.Exit(object); }
|
- 在这里,object的值与lock的值是一样的
- 简而言之,lock的写法是Monitor的一种简写
三 实例 将上一节C# lock实例中的 lock 关键字替换成 Monitor 类
3.1 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| class Program { public void PrintEven() { Monitor.Enter(this); try { for(int i = 0; i <= 10; i = i + 2) { Console.WriteLine(Thread.CurrentThread.Name + "--" + i); } } finally { Monitor.Exit(this); } } public void PrintOdd() { Monitor.Enter(this); try { for(int i = 1; i <= 10; i = i + 2) { Console.WriteLine(Thread.CurrentThread.Name + "--" + i); } } finally { Monitor.Exit(this); } } static void Main(string[] args) { Program program = new Program(); ThreadStart ts1 = new ThreadStart(program.PrintOdd); Thread t1 = new Thread(ts1); t1.Name = "打印奇数的线程"; t1.Start(); ThreadStart ts2 = new ThreadStart(program.PrintEven); Thread t2 = new Thread(ts2); t2.Name = "打印偶数的线程"; t2.Start(); } }
|
3.2 效果
3.3 说明
Monitor类的用法虽然比lock关键字复杂,但其能添加等待获得锁定的超时值,这样就不会无限期等待获得对象锁
使用TryEnter()方法可以给它传送一个超时值,决定等待获得对象锁的最常时间
使用TryEnter()方法设置获得对象锁的时间的代码如下, 该方法能在指定的毫秒数内结束线程,这样能避免线程之间的死锁现象
1
| Monitor.TryEnter(object, 毫秒数 );
|
此外,还能使用 Monitor 类中的 Wait() 方法让线程等待一定的时间,使用 Pulse() 方法通知处于等待状态的线程