[.net 多线程]Monitor

Monitor 类通过向单个线程授予对象锁来控制对对象的访问。对象锁提供限制访问代码块(通常称为临界区)的能力。当一个线程拥有对象的锁时,其他任何线程都不能获取该锁。还可以使用 Monitor 来确保不会允许其他任何线程访问正在由锁的所有者执行的应用程序代码节,除非另一个线程正在使用其他的锁定对象执行该代码。

 

Monitor通过enter和exit函数的组合,可以等效lock效果

1 Monitor.Enter(obj);
2 //...
3 Monitor.Exit(obj);
4 
5 lock(obj)
6 {
7      //...     
8 }
对象锁等效

与lock不同在于,Monitor更加灵活,可以通过Wait/Pulse,形成线程间的同步管理。当前获取到锁的线程(TA)通过Wait函数,释放对锁的控制,并将当前线程挂起为阻塞状态。这个时候其他线程就可以对锁资源进行竞争(假设在众多线程中TB获取到锁)。TA只有在接收到TB的Pulse信号,才能重新进入就绪状态,重新竞争锁资源。

注意Pulse函数是通知当前等待队列中第一个,PulseAll是通知所有等待队列中的线程。

 1 Thread th2 = new Thread(() =>
 2 {
 3     lock (aysncLock)
 4     {
 5         Console.WriteLine("th2 enter will wait");
 6         Monitor.Wait(aysncLock);
 7         Console.WriteLine("th2 continue");
 8     }
 9 });
10 Thread th3 = new Thread(() =>
11 {
12     lock (aysncLock)
13     {
14         Console.WriteLine("th3 enter will wait");
15         Monitor.Wait(aysncLock);
16         Console.WriteLine("th3 continue");
17     }
18 });
19 Thread th1 = new Thread(() => 
20 {
21     Thread.Sleep(TimeSpan.FromSeconds(1));
22     lock (aysncLock)
23     {
24         Console.WriteLine("th1 enter will pulseall");
25         Console.WriteLine($"th1 tell: th2 state: [{th2.ThreadState}]");
26         Console.WriteLine($"th1 tell: th3 state: [{th3.ThreadState}]");
27         //Monitor.PulseAll(aysncLock);
28         Monitor.Pulse(aysncLock);
29         Console.WriteLine($"th1 tell: th2 state: [{th2.ThreadState}]");
30         Console.WriteLine($"th1 tell: th3 state: [{th3.ThreadState}]");
31         Console.WriteLine("th1 exit");
32     }
33     Console.WriteLine($"th1 tell: th2 state: [{th2.ThreadState}]");
34     Console.WriteLine($"th1 tell: th3 state: [{th3.ThreadState}]");
35 });
36 
37 th1.Start();
38 th2.Start();
39 th3.Start();
40 Console.ReadKey();

使用Pulse结果:

th2、th3只有一个执行

使用PulseAll结果:

th2、th3均执行

 

posted on 2018-05-05 16:02  DeeperMiner  阅读(299)  评论(0编辑  收藏  举报

导航