zoukankan      html  css  js  c++  java
  • 线程同步之lock学习

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

    Lock的作用

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

    Lock实现本质

    通过System.Threading.Monitorenterexit方法实现的

    代码实例如下

     

    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代码如下

     

    View Code
     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

     

    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 }

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

    View Code
     1 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 }

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

    View Code
     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 }

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

    View Code
     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 

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

    View Code
     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 }

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

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

    View Code
     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 }

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



    View Code
     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 }

    整个类的代码如下

    View Code
      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 }
  • 相关阅读:
    HTTP断点续传 规格严格
    Java Shutdown 规格严格
    linux 命令源码 规格严格
    JTable调整列宽 规格严格
    linux 多CPU 规格严格
    Hello can not find git path 规格严格
    Kill 规格严格
    拜拜牛人 规格严格
    Swing 规格严格
    Debugging hangs in JVM (on AIX but methodology applicable to other platforms) 规格严格
  • 原文地址:https://www.cnblogs.com/wufengtinghai/p/2075914.html
Copyright © 2011-2022 走看看