博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线程同步之lock学习
阅读量:6842 次
发布时间:2019-06-26

本文共 9650 字,大约阅读时间需要 32 分钟。

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

 

转载于:https://www.cnblogs.com/wufengtinghai/archive/2011/06/09/2075914.html

你可能感兴趣的文章
浅谈Oracle存储过程中的一点小经验
查看>>
MySQL 高可用架构
查看>>
SCOM2012功能测试(15)—创建分布式应用程序
查看>>
openresty+lua+nginx_upstream_check_module等其他模块安装
查看>>
下载RPM包而不安装
查看>>
华为路由器命令解释大全
查看>>
点和圈的理论在软件测试中的思考
查看>>
Python将被纳入高考,小学生都在学Python,你慌了吗?
查看>>
PHP集成开发环境里面的www问题
查看>>
LVS负载均衡的搭建纯文本
查看>>
oracle中,约束、表名、Index等的名称长度限制最大只能30个字符
查看>>
Redis 5.0
查看>>
第一章 搭建一个通用的.net core项目框架
查看>>
使用Visual Studio 快速把 Json,Xml 字符串创建为一个实体类
查看>>
Asp.net 获取网页源代码
查看>>
Asp.net实现URL重写
查看>>
UVA 11796Dog Distance[平面几何]
查看>>
笔试题--mulicore编程题
查看>>
redis 常用命令
查看>>
Python语言学习 (十)1.1
查看>>