lock关键字

lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。

lock 关键字可确保当一个线程位于代码的临界区时,另一个线程不会进入该临界区。 如果其他线程尝试进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。
lock 关键字在块的开始处调用 Enter,而在块的结尾处调用 Exit。 ThreadInterruptedException 引发,如果 Interrupt 中断等待输入 lock 语句的线程。
通常,应避免锁定 public 类型,否则实例将超出代码的控制范围。

常见的结构 lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 违反此准则:
如果实例可以被公共访问,将出现 lock (this) 问题。
如果 MyType 可以被公共访问,将出现 lock (typeof (MyType)) 问题。
由于进程中使用同一字符串的任何其他代码都将共享同一个锁,所以出现 lock("myLock") 问题。
最佳做法是定义 private 对象来锁定, 或 private static 对象变量来保护所有实例所共有的数据。
在 lock 语句的正文不能使用 等待 关键字

1、lock的是引用类型的对象,string类型除外。

2、lock推荐的做法是使用静态的、只读的、私有的对象。

3、保证lock的对象在外部无法修改才有意义,如果lock的对象在外部改变了,对其他线程就会畅通无阻,失去了lock的意义。

 1 using System;
 2 using System.Threading;
 3 
 4 namespace Chapter1.Recipe9
 5 {
 6     class Program
 7     {
 8         static void Main(string[] args)
 9         {
10             Console.WriteLine("Incorrect counter");
11 
12             var c = new Counter();
13 
14             var t1 = new Thread(() => TestCounter(c));
15             var t2 = new Thread(() => TestCounter(c));
16             var t3 = new Thread(() => TestCounter(c));
17             t1.Start();
18             t2.Start();
19             t3.Start();
20             t1.Join();
21             t2.Join();
22             t3.Join();
23 
24             Console.WriteLine("Total count: {0}", c.Count);
25             Console.WriteLine("--------------------------");
26             Console.ReadKey();
27             Console.WriteLine("Correct counter");
28 
29             var c1 = new CounterWithLock();
30 
31             t1 = new Thread(() => TestCounter(c1));
32             t2 = new Thread(() => TestCounter(c1));
33             t3 = new Thread(() => TestCounter(c1));
34             t1.Start();
35             t2.Start();
36             t3.Start();
37             t1.Join();
38             t2.Join();
39             t3.Join();
40             Console.WriteLine("Total count: {0}", c1.Count);
41             Console.ReadKey();
42         }
43 
44         static void TestCounter(CounterBase c)
45         {
46             for (int i = 0; i < 100000; i++)
47             {
48                 c.Increment();
49                 c.Decrement();
50             }
51         }
52 
53         class Counter : CounterBase
54         {
55             public int Count { get; private set; }
56 
57             public override void Increment()
58             {
59                 Count++;
60             }
61 
62             public override void Decrement()
63             {
64                 Count--;
65             }
66         }
67 
68         class CounterWithLock : CounterBase
69         {
70             private static readonly object _syncRoot = new Object();
71 
72             public int Count { get; private set; }
73 
74             public override void Increment()
75             {
76                 lock (_syncRoot)
77                 {
78                     Count++;
79                 }
80             }
81 
82             public override void Decrement()
83             {
84                 lock (_syncRoot)
85                 {
86                     Count--;
87                 }
88             }
89         }
90 
91         abstract class CounterBase
92         {
93             public abstract void Increment();
94 
95             public abstract void Decrement();
96         }
97     }
98 }
View Code
原文地址:https://www.cnblogs.com/larry-xia/p/9213866.html