线程同步之lock学习

在应用程序中使用多个线程的一个好处是每个线程都可以异步执行。然而,线程的异步特性意味着必须协调对资源(如文件句柄、网络连接和内存)的访问。否则,两个或更多的线程可能在同一时间访问相同的资源,而每个线程都不知道其他线程的操作。结果将产生不可预知的数据损坏。这个时候我们就需要lock上场了。

Lock的作用

Lock获取给定对象的互斥锁,保证相应的代码块运行时,不会被其他线程中断;直到该对象被释放时其他线程才能访问相应的代码块;

Lock实现本质

通过System.Threading.Monitor的enter和exit方法实现的

代码实例如下

 

View Code
 
 1 public void PrintByInnerObj(object greating)
 2        { 
 3            Console.WriteLine(greating+"-- before lock");           
 4            object obj = new object();           
 5            lock(obj)
 6            {
 7                Console.WriteLine(greating + "-- is locking");
 8                Console.WriteLine(greating.ToString());
 9                System.Threading.Thread.Sleep(10000);
10            }
11            Console.WriteLine(greating + "--  has unlock");
12        }
 

 对应的MSIL代码如下

 

public void PrintByInnerObj(object greating)
 2        { 
 3            Console.WriteLine(greating+"-- before lock");           
 4            object obj = new object();           
 5            lock(obj)
 6            {
 7                Console.WriteLine(greating + "-- is locking");
 8                Console.WriteLine(greating.ToString());
 9                System.Threading.Thread.Sleep(10000);
10            }
11            Console.WriteLine(greating + "--  has unlock");
12        }

 

Lock的锁定范围

Lock的参数必须为引用类型的对象,该对象代表了锁定的范围,对象不同锁定的范围也不同。 

锁定参数为待锁定代码块内声明的对象,锁定范围为该代码块

View Code
 
 1 public void PrintByInnerObj(objectgreating)
 2 
 3 { 
 4 
 5 Console.WriteLine(greating+"-- before lock"); 
 6 
 7 object obj=newobject(); 
 8 
 9 lock(obj)
10 
11 {
12 
13 Console.WriteLine(greating+"-- is locking");
14 
15 Console.WriteLine(greating.ToString());
16 
17 System.Threading.Thread.Sleep(10000);
18 
19 }
20 
21 Console.WriteLine(greating+"-- has unlock");
22 
23 }
 

锁定参数为待锁定代码块所在类的私有字段,锁定范围为该类具体的一个实例

1 .method public hidebysig instance void  PrintByInnerObj(object greating) cil managed
 2 {
 3   // Code size       116 (0x74)
 4   .maxstack  2
 5   .locals init ([0object obj,
 6            [1bool '<>s__LockTaken0',
 7            [2object CS$2$0000,
 8            [3bool CS$4$0001)
 9   IL_0000:  nop
10   IL_0001:  ldarg.1
11   IL_0002:  ldstr      "-- before lock"
12   IL_0007:  call       string [mscorlib]System.String::Concat(object,
13                                                               object)
14   IL_000c:  call       void [mscorlib]System.Console::WriteLine(string)
15   IL_0011:  nop
16   IL_0012:  newobj     instance void [mscorlib]System.Object::.ctor()
17   IL_0017:  stloc.0
18   IL_0018:  ldc.i4.0
19   IL_0019:  stloc.1
20   .try
21   {
22     IL_001a:  ldloc.0
23     IL_001b:  dup
24     IL_001c:  stloc.2
25     IL_001d:  ldloca.s   '<>s__LockTaken0'
26     IL_001f:  call       void [mscorlib]System.Threading.Monitor::Enter(object,
27                                                                         bool&)
28     IL_0024:  nop
29     IL_0025:  nop
30     IL_0026:  ldarg.1
31     IL_0027:  ldstr      "-- is locking"
32     IL_002c:  call       string [mscorlib]System.String::Concat(object,
33                                                                 object)
34     IL_0031:  call       void [mscorlib]System.Console::WriteLine(string)
35     IL_0036:  nop
36     IL_0037:  ldarg.1
37     IL_0038:  callvirt   instance string [mscorlib]System.Object::ToString()
38     IL_003d:  call       void [mscorlib]System.Console::WriteLine(string)
39     IL_0042:  nop
40     IL_0043:  ldc.i4     0x2710
41     IL_0048:  call       void [mscorlib]System.Threading.Thread::Sleep(int32)
42     IL_004d:  nop
43     IL_004e:  nop
44     IL_004f:  leave.s    IL_0061
45   }  // end .try
46   finally
47   {
48     IL_0051:  ldloc.1
49     IL_0052:  ldc.i4.0
50     IL_0053:  ceq
51     IL_0055:  stloc.3
52     IL_0056:  ldloc.3
53     IL_0057:  brtrue.s   IL_0060
54     IL_0059:  ldloc.2
55     IL_005a:  call       void [mscorlib]System.Threading.Monitor::Exit(object)
56     IL_005f:  nop
57     IL_0060:  endfinally
58   }  // end handler
59   IL_0061:  nop
60   IL_0062:  ldarg.1
61   IL_0063:  ldstr      "--  has unlock"
62   IL_0068:  call       string [mscorlib]System.String::Concat(object,
63                                                               object)
64   IL_006d:  call       void [mscorlib]System.Console::WriteLine(string)
65   IL_0072:  nop
66   IL_0073:  ret
67 // end of method MyLockTest::PrintByInnerObj
复制代码

锁定参数为待锁定代码块所在类的私有静态字段,锁定范围为该类所有的实例


复制代码
 1 public void PrintByInnerObj(objectgreating)
 2 
 3 
 4 
 5 Console.WriteLine(greating+"-- before lock"); 
 6 
 7 object obj=newobject(); 
 8 
 9 lock(obj)
10 
11 {
12 
13 Console.WriteLine(greating+"-- is locking");
14 
15 Console.WriteLine(greating.ToString());
16 
17 System.Threading.Thread.Sleep(10000);
18 
19 }
20 
21 Console.WriteLine(greating+"-- has unlock");
22 
23 }

锁定参数为某一字符串,锁定范围为与该字符串值相等的所有字符串

public void PrintByInstanceObj(objectgreating)
 2 
 3 {
 4 
 5 Console.WriteLine(greating+"-- before lock"); 
 6 
 7 lock (instanceObj)
 8 
 9 {
10 
11 Console.WriteLine(greating+"-- is locking");
12 
13 Console.WriteLine(greating.ToString());
14 
15 System.Threading.Thread.Sleep(10000);
16 
17 }
18 
19 Console.WriteLine(greating+"-- has unlock");
20 
21 }

锁定参数为this,锁定范围为所有能访问到this的地方

1 public void PrintLockByStaticObj(objectgreating)
 2 
 3 {
 4 
 5 Console.WriteLine(greating+"-- before lock"); 
 6 
 7 lock (staticObj)
 8 
 9 {
10 
11 Console.WriteLine(greating+"-- is locking");
12 
13 Console.WriteLine(greating.ToString());
14 
15 Thread.Sleep(10000);
16 
17 }
18 
19 Console.WriteLine(greating+"-- has unlock");
20 
21 }

锁定参数为某个类的System.Type的实例,锁定范围为所有的地方

锁定public的实例字段,锁定范围同锁定this

 1 public void PrintLockByStringObj(objectgreating)
 2 
 3 {
 4 
 5 Console.WriteLine(greating+"-- before lock"); 
 6 
 7 lock (stringObj)
 8 
 9 {
10 
11 Console.WriteLine(greating+"-- is locking");
12 
13 Console.WriteLine(greating.ToString());
14 
15 System.Threading.Thread.Sleep(10000);
16 
17 }
18 
19 Console.WriteLine(greating+"--has unlock");
20 
21 }
22 
23 
24 public void PrintLockByString(objectgreating)
25 
26 {
27 
28 Console.WriteLine(greating+"-- before lock"); 
29 
30 lock ("lock")
31 
32 {
33 
34 Console.WriteLine(greating+"-- is locking");
35 
36 Console.WriteLine(greating.ToString());
37 
38 System.Threading.Thread.Sleep(10000);
39 
40 }
41 
42 Console.WriteLine(greating+"--has unlock");
43 
44 

锁定参数为public的静态字段,锁定范围与锁定system.type相同



 1 public void PrintLockByThis(objectgreating)
 2 
 3 {
 4 
 5 Console.WriteLine(greating+"-- before lock"); 
 6 
 7 lock (this)
 8 
 9 {
10 
11 Console.WriteLine(greating+"-- is locking");
12 
13 Console.WriteLine(greating.ToString());
14 
15 System.Threading.Thread.Sleep(10000);
16 
17 }
18 
19 Console.WriteLine(greating+"--has unlock");
20 
21 }

整个类的代码如下

1 public void PrintLockByPublicInstanceObj(objectgreating)
 2 
 3 {
 4 
 5 Console.WriteLine(greating+"-- before lock");
 6 
 7 lock (publicInstanceObj)
 8 
 9 {
10 
11 Console.WriteLine(greating+"-- is locking");
12 
13 Console.WriteLine(greating.ToString());
14 
15 System.Threading.Thread.Sleep(10000);
16 
17 }
18 
19 Console.WriteLine(greating+"--has unlock");
20 
21 }
 1 public void PrintLockByPublicStaticObj(objectgreating)
 2 
 3 {
 4 
 5 Console.WriteLine(greating+"-- before lock");
 6 
 7 lock (publicStaticObj)
 8 
 9 {
10 
11 Console.WriteLine(greating+"-- is locking");
12 
13 Console.WriteLine(greating.ToString());
14 
15 System.Threading.Thread.Sleep(10000);
16 
17 }
18 
19 Console.WriteLine(greating+"--has unlock");
20 
21 }

整个类的代码如下

1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading;
  6 
  7 namespace LockCVolatileCA
  8 {
  9    public class MyLockTest
 10     {
 11        private static object staticObj = new object();
 12        private object instanceObj = new object();
 13        public static object publicStaticObj = new object();
 14        public object publicInstanceObj = new object();
 15        private string stringObj = "lock";
 16        private static Int32 i = new int()  ;
 17 
 18        public void PrintByInnerObj(object greating)
 19        { 
 20            Console.WriteLine(greating+"-- before lock");          
 21            object obj = new object();           
 22            lock(obj)
 23            {
 24                Console.WriteLine(greating + "-- is locking");
 25                Console.WriteLine(greating.ToString());
 26                System.Threading.Thread.Sleep(10000);
 27            }
 28            Console.WriteLine(greating + "--  has unlock");
 29        }
 30 
 31        public void PrintByInstanceObj(object greating)
 32        {
 33            Console.WriteLine(greating + "-- before lock");                    
 34            lock (instanceObj)
 35            {
 36                Console.WriteLine(greating + "-- is locking");
 37                Console.WriteLine(greating.ToString());
 38                System.Threading.Thread.Sleep(10000);
 39            }
 40            Console.WriteLine(greating + "--  has unlock");
 41        }
 42 
 43        public void PrintLockByStaticObj(object greating)
 44        {
 45            Console.WriteLine(greating + "-- before lock");           
 46            lock (staticObj)
 47            {
 48                Console.WriteLine(greating + "-- is locking");
 49                Console.WriteLine(greating.ToString());
 50                Thread.Sleep(10000);
 51            }
 52            Console.WriteLine(greating + "-- has unlock");
 53        }
 54 
 55        public void PrintLockByClass(object greating)
 56        {
 57            Console.WriteLine(greating + "-- before lock");         
 58            lock (typeof(MyLockTest))
 59            {
 60                Console.WriteLine(greating + "-- is locking");
 61                Console.WriteLine(greating.ToString());
 62                Thread.Sleep(1000);
 63            }
 64            Console.WriteLine(greating + "-- has unlock");
 65        }
 66 
 67        public void PrintLockByThis(object greating)
 68        {
 69            Console.WriteLine(greating + "-- before lock");        
 70            lock (this)
 71            {
 72                Console.WriteLine(greating + "-- is locking");
 73                Console.WriteLine(greating.ToString());
 74                System.Threading.Thread.Sleep(10000);
 75            }
 76            Console.WriteLine(greating + "--has unlock");
 77        }
 78 
 79        public void PrintLockByStringObj(object greating)
 80        {
 81            Console.WriteLine(greating + "-- before lock");       
 82            lock (stringObj)
 83            {
 84                Console.WriteLine(greating + "-- is locking");
 85                Console.WriteLine(greating.ToString());
 86                System.Threading.Thread.Sleep(10000);
 87            }
 88            Console.WriteLine(greating + "--has unlock");
 89        }
 90 
 91        public void PrintLockByString(object greating)
 92        {
 93            Console.WriteLine(greating + "-- before lock");         
 94            lock ("lock")
 95            {
 96                Console.WriteLine(greating + "-- is locking");
 97                Console.WriteLine(greating.ToString());
 98                System.Threading.Thread.Sleep(10000);
 99            }
100            Console.WriteLine(greating + "--has unlock");
101        }
102 
103        public void PrintLockByPublicStaticObj(object greating)
104        {
105            Console.WriteLine(greating + "-- before lock");           
106            lock (publicStaticObj)
107            {
108                Console.WriteLine(greating + "-- is locking");
109                Console.WriteLine(greating.ToString());
110                System.Threading.Thread.Sleep(10000);
111            }
112            Console.WriteLine(greating + "--has unlock");
113        }
114 
115        public void PrintLockByPublicInstanceObj(object greating)
116        {
117            Console.WriteLine(greating + "-- before lock");
118            lock (publicInstanceObj)
119            {
120                Console.WriteLine(greating + "-- is locking");
121                Console.WriteLine(greating.ToString());
122                System.Threading.Thread.Sleep(10000);
123            }
124            Console.WriteLine(greating + "--has unlock");
125        }       
126     }
127 }
原文地址:https://www.cnblogs.com/Leo_wl/p/2547815.html