当前位置: 首页 > news >正文

线程同步之lock学习

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

Lock的作用

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

Lock实现本质

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

代码实例如下

 

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

 

ExpandedBlockStart.gif 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  ([ 0 object  obj,
 6             [ 1 bool   ' <>s__LockTaken0 ' ,
 7             [ 2 object  CS$ 2 $ 0000 ,
 8             [ 3 bool  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的参数必须为引用类型的对象,该对象代表了锁定的范围,对象不同锁定的范围也不同。 

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

 

ExpandedBlockStart.gif 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  }

 

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

 

ExpandedBlockStart.gif 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  }

 

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

 

ExpandedBlockStart.gif 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  }

 

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

 

ExpandedBlockStart.gif 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的地方

 

ExpandedBlockStart.gif 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

 

ExpandedBlockStart.gif 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相同



ExpandedBlockStart.gif 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  }

 

 

整个类的代码如下

 

ExpandedBlockStart.gif 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  }

 

相关文章:

  • 减少Linux下Squid服务器的TIME_WAIT
  • 什么是云存储技术与云存储服务?
  • HTTP协议header头域
  • Web开发小结 - 2
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • 【原创】关于mobile 和wince系统定制开发的最大区别
  • 军卫一号军卫二号相关论坛资料汇总
  • 如何在linux下解压缩rar格式的文件压缩包
  • Answer:关于C#连续赋值的面试题
  • 准备MCITP考试
  • Effective Java学习笔记-对于所有对象都通用的方法
  • SQL绕过注入最新代码
  • Context在android中的作用与实现
  • Android开发之Java集合类性能分析
  • ylmf os 里最小化后找不到了,只能用alt+tab查看?
  • extjs4学习之配置
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • Java编程基础24——递归练习
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • Redux 中间件分析
  • vue2.0一起在懵逼的海洋里越陷越深(四)
  • vue学习系列(二)vue-cli
  • webpack+react项目初体验——记录我的webpack环境配置
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 复习Javascript专题(四):js中的深浅拷贝
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 前端面试之CSS3新特性
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 学习JavaScript数据结构与算法 — 树
  • 原生Ajax
  • 再次简单明了总结flex布局,一看就懂...
  • 正则与JS中的正则
  • scrapy中间件源码分析及常用中间件大全
  • 容器镜像
  • 直播平台建设千万不要忘记流媒体服务器的存在 ...
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • #HarmonyOS:基础语法
  • $.ajax,axios,fetch三种ajax请求的区别
  • ( 10 )MySQL中的外键
  • (Oracle)SQL优化技巧(一):分页查询
  • (附源码)ssm高校升本考试管理系统 毕业设计 201631
  • (附源码)计算机毕业设计SSM基于健身房管理系统
  • (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
  • (算法二)滑动窗口
  • (一)SpringBoot3---尚硅谷总结
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • .jks文件(JAVA KeyStore)
  • .NET Core实战项目之CMS 第十二章 开发篇-Dapper封装CURD及仓储代码生成器实现
  • .Net FrameWork总结
  • .NET Standard / dotnet-core / net472 —— .NET 究竟应该如何大小写?
  • .NET处理HTTP请求
  • .NET框架设计—常被忽视的C#设计技巧
  • ;号自动换行