关于“GUI 博士的忠告:切勿锁定类型对象!”的实验
1
using System;
2
using System.Threading;
3
4
namespace TestLab.System.Threading
5
{
6
//在遇到线程类问题的时候,我们需要注意:
7
//a线程在执行“代码中连续的语句”a1、a2时,并不代表他们在实际执行时也是连续了(也许是连续的也许不是)
8
//也就是说此时b线程完全有可能在a1、a2之间做“小三”,这是上帝(CPU)的意思
9
internal class LowThread1
10
{
11
private static int _data;
12
private static object _lockObj = new object();
13
private string _name;
14
15
public int Data
16
{
17
get { return _data; }
18
}
19
20
public LowThread1(string name)
21
{
22
this._name = name;
23
Console.WriteLine("{1}创建新的LowLevel1对象:{0}", name, DateTime.Now);
24
}
25
26
public void FightOver1()
27
{
28
Console.WriteLine("{1}方法名:FightOver1------{0}", this._name, DateTime.Now);
29
Console.WriteLine("{2}线程名:{0}------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);
30
Console.WriteLine("{1}正在抢夺操作
------{0}", this._name, DateTime.Now);
31
32
lock (_lockObj)
33
{
34
Console.WriteLine("{2}线程名:{0} 开始操作资源
.------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);
35
_data++;
36
Console.WriteLine("{2}操作完毕,现在的数据值:{0}------{1}", _data, this._name, DateTime.Now);
37
Console.WriteLine("{1}开始Sleep 5 秒------{0}", this._name, DateTime.Now);
38
Thread.Sleep(5000);
39
}
40
41
Console.WriteLine("{2}线程名:{0} 已经离开操作------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);
42
}
43
public void FightOver2()
44
{
45
Console.WriteLine("{1}方法名:FightOver1------{0}", this._name, DateTime.Now);
46
Console.WriteLine("{2}线程名:{0}------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);
47
Console.WriteLine("{1}正在抢夺操作
------{0}", this._name, DateTime.Now);
48
49
lock(typeof(LowThread1))
50
{
51
Console.WriteLine("{2}线程:{0} 在LowLevel1.FightOver2()中开始睡 5 秒------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);
52
Thread.Sleep(5000);
53
}
54
Console.WriteLine("{2}线程名:{0} 已经离开操作------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);
55
}
56
public void FightOver3_1()
57
{
58
Console.WriteLine("{1}方法名:FightOver1------{0}", this._name, DateTime.Now);
59
Console.WriteLine("{2}线程名:{0}------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);
60
Console.WriteLine("{1}正在抢夺操作
------{0}", this._name, DateTime.Now);
61
62
lock (this)
63
{
64
Console.WriteLine("{2}线程:{0} 在LowLevel1.FightOver2()中开始睡 5 秒------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);
65
Thread.Sleep(5000);
66
}
67
Console.WriteLine("{2}线程名:{0} 已经离开操作------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);
68
}
69
public void FightOver3_2()
70
{
71
Console.WriteLine("{1}方法名:FightOver1------{0}", this._name, DateTime.Now);
72
Console.WriteLine("{2}线程名:{0}------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);
73
Console.WriteLine("{1}正在抢夺操作
------{0}", this._name, DateTime.Now);
74
75
lock (this)
76
{
77
Console.WriteLine("{2}线程:{0} 在LowLevel1.FightOver2()中开始睡 1 秒------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);
78
Thread.Sleep(1000);
79
}
80
Console.WriteLine("{2}线程名:{0} 已经离开操作------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);
81
}
82
}
83
public class LowThreadDrive1
84
{
85
public void Drive1()
86
{
87
LowThread1 ll1 = new LowThread1("name1");
88
LowThread1 ll2 = new LowThread1("name2");
89
90
Thread th1 = new Thread(ll1.FightOver1);
91
Thread th2 = new Thread(ll2.FightOver2);
92
93
th1.Name = "线程1";
94
th2.Name = "线程2";
95
96
th1.Start();
97
th2.Start();
98
99
}
100
public void Drive2()
101
{
102
LowThread1 ll1 = new LowThread1("ll1");
103
LowThreadHelp1 llh = new LowThreadHelp1("llh");
104
105
Thread th1 = new Thread(ll1.FightOver2);
106
Thread th2 = new Thread(llh.FightHelp2);
107
108
th1.Name = "线程1";
109
th2.Name = "线程2";
110
111
th1.Start();
112
Thread.Sleep(1000);
113
th2.Start();
114
}
115
public void Drive3()
116
{
117
LowThread1 ll1 = new LowThread1("ll1");
118
LowThreadHelp1 llh = new LowThreadHelp1("llh");
119
120
Thread th1 = new Thread(ll1.FightOver3_1);
121
Thread th2 = new Thread(llh.FightHelp3);
122
123
th1.Name = "线程1";
124
th2.Name = "线程2";
125
126
th1.Start();
127
Thread.Sleep(500);
128
th2.Start(ll1);
129
}
130
//注意 FightOver3和FightOver3_2()的不同之处在于lock块中,线程的sleep的时间前者5s后者1s
131
//此处只是锁住了LowThread1的一个实例,并不是所有的实例。不同实例调用lock(this)并不相关。
132
public void Drive4()
133
{
134
LowThread1 ll1 = new LowThread1("ll1");
135
LowThread1 ll2 = new LowThread1("ll2");
136
137
Thread th1 = new Thread(ll1.FightOver3_1);
138
Thread th2 = new Thread(ll2.FightOver3_2);
139
140
th1.Name = "线程1";
141
th2.Name = "线程2";
142
143
th1.Start();
144
Thread.Sleep(500);
145
th2.Start();
146
}
147
}
148
internal class LowThreadHelp1
149
{
150
private string _name;
151
152
public LowThreadHelp1(string name)
153
{
154
this._name = name;
155
Console.WriteLine("{1}创建新的LowLevel1Help对象:{0}", name, DateTime.Now);
156
}
157
158
//这个方法对应的是LowLevel1.FightOver2()
159
//当有线程调用LowLevel1.FightOver2()时,LowLevel1的Type对象被锁了,需要在Lock中睡5s
160
//如果在5s内有线程调用这个FightHelp2()方法时,这个线程将被阻塞,进入线程列队
161
//等到5s过后才能调用FightHelp2()中Lock里面的东西
162
public void FightHelp2()
163
{
164
lock (typeof(LowThread1))
165
{
166
Console.WriteLine("{1}执行LowLevel1Help.FightHelp2():{0}", this._name, DateTime.Now);
167
}
168
}
169
//这个方法对象的是LowLevel1.FightOver3()
170
//当有线程执行LowLevel1.FightOver2()时,执行这个方法的对象被锁了,需要在Lock中睡5s
171
//如果5s内有线程调用这个FightHelp3()方法时,这个线程将被阻塞,进入线程列队
172
//等待5s过后才能调用FightHelp3()中Lock里的东西
173
public void FightHelp3(object obj)
174
{
175
LowThread1 ll1 = (LowThread1)obj;
176
lock (ll1)
177
{
178
Console.WriteLine("{1}执行LowLevel1Help.FightHelp3()------{0}", this._name, DateTime.Now);
179
Console.WriteLine("{2}得到LowLevel1.Data:{0}------{1}", ll1.Data, this._name, DateTime.Now);
180
}
181
}
182
}
183
}
184
using System;2
using System.Threading;3

4
namespace TestLab.System.Threading5
{6
//在遇到线程类问题的时候,我们需要注意:7
//a线程在执行“代码中连续的语句”a1、a2时,并不代表他们在实际执行时也是连续了(也许是连续的也许不是)8
//也就是说此时b线程完全有可能在a1、a2之间做“小三”,这是上帝(CPU)的意思9
internal class LowThread110
{11
private static int _data;12
private static object _lockObj = new object();13
private string _name;14

15
public int Data16
{17
get { return _data; }18
}19

20
public LowThread1(string name)21
{22
this._name = name;23
Console.WriteLine("{1}创建新的LowLevel1对象:{0}", name, DateTime.Now);24
}25

26
public void FightOver1()27
{28
Console.WriteLine("{1}方法名:FightOver1------{0}", this._name, DateTime.Now);29
Console.WriteLine("{2}线程名:{0}------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);30
Console.WriteLine("{1}正在抢夺操作
------{0}", this._name, DateTime.Now);31

32
lock (_lockObj)33
{34
Console.WriteLine("{2}线程名:{0} 开始操作资源
.------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);35
_data++;36
Console.WriteLine("{2}操作完毕,现在的数据值:{0}------{1}", _data, this._name, DateTime.Now);37
Console.WriteLine("{1}开始Sleep 5 秒------{0}", this._name, DateTime.Now);38
Thread.Sleep(5000);39
}40

41
Console.WriteLine("{2}线程名:{0} 已经离开操作------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);42
}43
public void FightOver2()44
{45
Console.WriteLine("{1}方法名:FightOver1------{0}", this._name, DateTime.Now);46
Console.WriteLine("{2}线程名:{0}------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);47
Console.WriteLine("{1}正在抢夺操作
------{0}", this._name, DateTime.Now);48

49
lock(typeof(LowThread1))50
{51
Console.WriteLine("{2}线程:{0} 在LowLevel1.FightOver2()中开始睡 5 秒------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);52
Thread.Sleep(5000);53
}54
Console.WriteLine("{2}线程名:{0} 已经离开操作------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);55
}56
public void FightOver3_1()57
{58
Console.WriteLine("{1}方法名:FightOver1------{0}", this._name, DateTime.Now);59
Console.WriteLine("{2}线程名:{0}------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);60
Console.WriteLine("{1}正在抢夺操作
------{0}", this._name, DateTime.Now);61

62
lock (this)63
{64
Console.WriteLine("{2}线程:{0} 在LowLevel1.FightOver2()中开始睡 5 秒------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);65
Thread.Sleep(5000);66
}67
Console.WriteLine("{2}线程名:{0} 已经离开操作------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);68
}69
public void FightOver3_2()70
{71
Console.WriteLine("{1}方法名:FightOver1------{0}", this._name, DateTime.Now);72
Console.WriteLine("{2}线程名:{0}------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);73
Console.WriteLine("{1}正在抢夺操作
------{0}", this._name, DateTime.Now);74

75
lock (this)76
{77
Console.WriteLine("{2}线程:{0} 在LowLevel1.FightOver2()中开始睡 1 秒------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);78
Thread.Sleep(1000);79
}80
Console.WriteLine("{2}线程名:{0} 已经离开操作------{1}", Thread.CurrentThread.Name, this._name, DateTime.Now);81
}82
}83
public class LowThreadDrive184
{85
public void Drive1()86
{87
LowThread1 ll1 = new LowThread1("name1");88
LowThread1 ll2 = new LowThread1("name2");89

90
Thread th1 = new Thread(ll1.FightOver1);91
Thread th2 = new Thread(ll2.FightOver2);92

93
th1.Name = "线程1";94
th2.Name = "线程2";95

96
th1.Start();97
th2.Start();98

99
}100
public void Drive2()101
{102
LowThread1 ll1 = new LowThread1("ll1");103
LowThreadHelp1 llh = new LowThreadHelp1("llh");104

105
Thread th1 = new Thread(ll1.FightOver2);106
Thread th2 = new Thread(llh.FightHelp2);107

108
th1.Name = "线程1";109
th2.Name = "线程2";110

111
th1.Start();112
Thread.Sleep(1000);113
th2.Start();114
}115
public void Drive3()116
{117
LowThread1 ll1 = new LowThread1("ll1");118
LowThreadHelp1 llh = new LowThreadHelp1("llh");119

120
Thread th1 = new Thread(ll1.FightOver3_1);121
Thread th2 = new Thread(llh.FightHelp3);122

123
th1.Name = "线程1";124
th2.Name = "线程2";125

126
th1.Start();127
Thread.Sleep(500);128
th2.Start(ll1);129
}130
//注意 FightOver3和FightOver3_2()的不同之处在于lock块中,线程的sleep的时间前者5s后者1s131
//此处只是锁住了LowThread1的一个实例,并不是所有的实例。不同实例调用lock(this)并不相关。132
public void Drive4()133
{134
LowThread1 ll1 = new LowThread1("ll1");135
LowThread1 ll2 = new LowThread1("ll2");136

137
Thread th1 = new Thread(ll1.FightOver3_1);138
Thread th2 = new Thread(ll2.FightOver3_2);139

140
th1.Name = "线程1";141
th2.Name = "线程2";142

143
th1.Start();144
Thread.Sleep(500);145
th2.Start();146
}147
}148
internal class LowThreadHelp1149
{150
private string _name;151

152
public LowThreadHelp1(string name)153
{154
this._name = name;155
Console.WriteLine("{1}创建新的LowLevel1Help对象:{0}", name, DateTime.Now);156
}157

158
//这个方法对应的是LowLevel1.FightOver2()159
//当有线程调用LowLevel1.FightOver2()时,LowLevel1的Type对象被锁了,需要在Lock中睡5s160
//如果在5s内有线程调用这个FightHelp2()方法时,这个线程将被阻塞,进入线程列队161
//等到5s过后才能调用FightHelp2()中Lock里面的东西162
public void FightHelp2()163
{164
lock (typeof(LowThread1))165
{166
Console.WriteLine("{1}执行LowLevel1Help.FightHelp2():{0}", this._name, DateTime.Now);167
}168
}169
//这个方法对象的是LowLevel1.FightOver3()170
//当有线程执行LowLevel1.FightOver2()时,执行这个方法的对象被锁了,需要在Lock中睡5s171
//如果5s内有线程调用这个FightHelp3()方法时,这个线程将被阻塞,进入线程列队172
//等待5s过后才能调用FightHelp3()中Lock里的东西173
public void FightHelp3(object obj)174
{175
LowThread1 ll1 = (LowThread1)obj;176
lock (ll1)177
{178
Console.WriteLine("{1}执行LowLevel1Help.FightHelp3()------{0}", this._name, DateTime.Now);179
Console.WriteLine("{2}得到LowLevel1.Data:{0}------{1}", ll1.Data, this._name, DateTime.Now);180
}181
}182
}183
}184


浙公网安备 33010602011771号