Lock和Monitor没区别,简单来讲Lock是Monitor的进一步封装
锁定的目的:由于多个线程并行/并发处理同一个“数据对象”(比如:在其它线程的某个地方发生了Clear、Add、Remove、Change等操作),导致“数据对象”不断变化,没法用了,所以,为了保证数据在某个计算时刻的“恒定”,使用排它锁将“数据对象”锁定,然后就视该“数据对象”为“一个恒定量”进行逻辑处理。
1.代码使用
| Lock | Monitor | 
| Lock(obj) {
 执行任务
 }
 | Monitor.Enter(obj); try{
 执行任务
 }finally
 {
 Monitor.Exit(obj);
 }
 | 
2.Example
- 使用Task.WaitAll 等待子线程完成
- Monitor琐死要变化的参数,使其在使用时无法突变
- 使用Stopwatch观察子线程执行时长
| 12
 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
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 
 | static void Main(){
 
 Console.WriteLine("Monitor Demo ...");
 
 int nTasks = 0;
 object obj = nTasks;
 
 List<Task> tasks = new List<Task>();
 
 try
 {
 Console.WriteLine($"nTasks:{nTasks};MainThreadId:{Thread.CurrentThread.ManagedThreadId}");
 Stopwatch sw = new Stopwatch();
 sw.Start();
 
 for (int ctr=0;ctr<10;ctr++)
 {
 tasks.Add(Task.Run(async() => {
 Console.ForegroundColor = ConsoleColor.White;
 Console.WriteLine($"子任务{Thread.CurrentThread.ManagedThreadId} 延时5000ms");
 await Task.Delay(5000);
 Monitor.Enter(obj);
 try
 {
 nTasks++;
 Console.WriteLine($"nTasks:{nTasks};SubThreadId:{Thread.CurrentThread.ManagedThreadId}");
 }
 finally
 {
 Monitor.Exit(obj);
 }
 }));
 
 }
 Console.ForegroundColor = ConsoleColor.Green;
 Console.WriteLine("不会堵塞");
 Console.ForegroundColor = ConsoleColor.Red;
 Console.WriteLine("使用Task.WaitAll(tasks.ToArray());等待tasks子线程结束,才执行主线程:等待子线程结束");
 Task.WaitAll(tasks.ToArray());
 sw.Stop();
 Console.ForegroundColor = ConsoleColor.Red;
 Console.WriteLine("开始执行主线程");
 Console.WriteLine($"执行时长:{sw.ElapsedMilliseconds}ms");
 Console.WriteLine($"nTasks:{nTasks};MainThreadId:{Thread.CurrentThread.ManagedThreadId}");
 Console.ForegroundColor = ConsoleColor.White;
 }
 catch(AggregateException e)
 {
 String msg = String.Empty;
 foreach (var ie in e.InnerExceptions)
 {
 Console.WriteLine("{0}", ie.GetType().Name);
 if (!msg.Contains(ie.Message))
 msg += ie.Message + Environment.NewLine;
 }
 Console.WriteLine("\nException Message(s):");
 Console.WriteLine(msg);
 }
 Console.ReadLine();
 }
 
 | 
效果
