您的位置:首页 > 编程语言 > C#

C#多线程编程之:Monitor使用示例及Mutex简介

2011-03-25 10:39 731 查看
Monitor类功效和lock类似:

1 System.Object obj = (System.Object)x;
2 System.Threading.Monitor.Enter(obj);
3 try
4 {
5    DoSomething();
6 }
7 finally
8 {
9    System.Threading.Monitor.Exit(obj);
10 }


  lock关键字比Monitor简洁,其实lock就是对Monitor的Enter和Exit的一个封装。

  另外,Monitor还有几个常用的方法:

  (1) TryEnter

  TryEnter能够有效的决绝长期死等的问题,如果在一个并发经常发生,而且持续时间长的环境中使用TryEnter,可以有效防止死锁或者长时间的等待。

  比如我们可以设置一个等待时间:

  bool gotLock = Monitor.TryEnter(myobject,1000)

  让当前线程在等待1000秒后根据返回的bool值来决定是否继续下面的操作。

  (2) Pulse、PulseAll、Wait

  Pulse以及PulseAll还有Wait方法是成对使用的,它们能让你更精确的控制线程之间的并发。

  示例代码:

1 using System.Threading;
2
3 public class Program
4 {
5     //同步对象
6     static object ball = new object();
7
8     public static void Main()
9     {
10         //创建并启动线程
11         Thread threadPing = new Thread(ThreadPingProc);
12         Thread threadPong = new Thread(ThreadPongProc);
13
14         threadPing.Start();
15         threadPong.Start();
16
17         System.Console.ReadLine();
18     }
19
20     static void ThreadPingProc()
21     {
22         System.Console.WriteLine("Thread Ping Start!");
23
24         //锁定ball
25         lock (ball)
26         {
27             for (int i = 0; i < 5; i++)
28             {
29                 System.Console.WriteLine("ThreadPing: Ping ");
30                 //通知队列中锁定对象ball的状态更改
31                 Monitor.Pulse(ball);
32                 //释放ball对象上的锁,并阻止该线程,直到它重新获得ball对象锁
33                 Monitor.Wait(ball);
34             }
35
36             //通知队列中锁定对象ball的状态更改
37             Monitor.Pulse(ball);
38         }
39
40         System.Console.WriteLine("ThreadPing: Bye!");
41     }
42
43     static void ThreadPongProc()
44     {
45         System.Console.WriteLine("Thread Pong Start!");
46
47         //锁定ball
48         lock (ball)
49         {
50             for (int i = 0; i < 5; i++)
51             {
52                 System.Console.WriteLine("ThreadPong: Pong ");
53                 //通知队列中锁定对象ball的状态更改
54                 Monitor.Pulse(ball);
55                 //释放ball对象上的锁,并阻止该线程,直到它重新获得ball对象锁
56                 Monitor.Wait(ball);
57             }
58
59             //通知队列中锁定对象ball的状态更改
60             Monitor.Pulse(ball);
61         }
62
63         System.Console.WriteLine("ThreadPong: Bye!");
64     }
65 }


  执行结果如下:

  ThreadPing: Hello!

  ThreadPing: Ping
  ThreadPong: Hello!
  ThreadPong: Pong
  ThreadPing: Ping
  ThreadPong: Pong
  ThreadPing: Ping
  ThreadPong: Pong
  ThreadPing: Ping
  ThreadPong: Pong
  ThreadPing: Ping
  ThreadPong: Pong
  ThreadPing: Bye!

  ThreadPong: Bye!
  当threadPing进程进入ThreadPingProc锁定ball并调用Monitor.Pulse(ball )后,它通知threadPong从阻塞队列进入准备队列。当threadPing调用Monitor.Wait(ball)阻塞自己后,它放弃了了对ball的锁定,所以threadPong得以执行。PulseAll与Pulse方法类似,不过它是向所有在阻塞队列中的进程发送通知信号,如果只有一个线程被阻塞,那么请使用Pulse方法。

Mutex 对象
   Mutex与Monitor类似,这里不再累赘。需要注意的是Mutex分两种:一种是本地Mutex,一种是系统级Mutex。系统级Mutex可以用来进行跨进程间的线程的同步。尽管 Mutex 可以用于进程内的线程同步,但是使用 Monitor 通常更为可取,因为Monitor是专门为 .NET Framework 而设计的,因而它可以更好地利用资源。相比之下,Mutex 类是 Win32 构造的包装。尽管 Mutex 比Monitor更为强大,但是相对于 Monitor 类,它所需要的互操作转换更消耗计算资源。


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: