1.lock

   Lock锁定一段代码

   lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。

   通常,应避免锁定 public 类型,否则实例将超出代码的控制范围。常见的结构 lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 

   违反此准则:

  • 如果实例可以被公共访问,将出现 lock (this) 问题。
  • 如果 MyType 可以被公共访问,将出现 lock(typeof (MyType)) 问题。

   由于进程中使用同一字符串的任何其他代码将共享同一个锁,所以出现 lock(“myLock”) 问题。最佳做法是定义 private 对象来锁定, private static 对象变量来保护所有实例所共有的数据。

2.Monitor 

  Monitor用来锁定一个对象

  Monitor具有以下的功能:

  • 与某个对象关联。
  • 它是未绑定的,可以直接从上下文中引用。
  • 不能创建Monitor实例

 将为每个同步对象维护以下信息:

  • 对当前持有锁的线程的引用。
  • 对就绪队列的引用,它包含准备获取锁的线程。
  •  对等待队列的引用,它包换正在等待锁定对象状态变化通知的线程。

Code:   

 1 class MonitorSample
 2     {
 3         const int MAX_LOOP_TIME = 1000;
 4         Queue mQueue;
 5 
 6         public MonitorSample()
 7         {
 8             mQueue = new Queue();
 9         }
10         public void FirstThread()
11         {
12             int counter = 0;
13             lock (mQueue)
14             {
15                 while (counter < MAX_LOOP_TIME)
16                 {
17                     Monitor.Wait(mQueue);
18                     mQueue.Enqueue(counter);
19                     Console.WriteLine("Write:{0}", counter);
20                     Monitor.Pulse(mQueue);
21                     counter++;
22                 }
23             }
24         }
25         public void SecondThread()
26         {
27             lock (mQueue)
28             {
29                 Monitor.Pulse(mQueue);
30                 while (Monitor.Wait(mQueue, 1000))
31                 {
32                     int counter = (int)mQueue.Dequeue();
33                     Console.WriteLine("Read:{0}",counter);
34                     Monitor.Pulse(mQueue);
35                 }
36             }
37         }
38         public int GetQueueCount()
39         {
40             return mQueue.Count;
41         }
42 
43         static void Main(string[] args)
44         {
45             MonitorSample test = new MonitorSample();
46             Thread tFirst = new Thread(new ThreadStart(test.FirstThread));
47             Thread tSecond = new Thread(new ThreadStart(test.SecondThread));
48             tFirst.Start();
49             tSecond.Start();
50             tFirst.Join();
51             tSecond.Join();
52             Console.WriteLine("Queue Count = " + test.GetQueueCount().ToString());
53             Console.ReadKey();
54         }
55     }
View Code

相关文章: