關于“GUI 博士的忠告:切勿鎖定類型對象!”的實驗
1
using System;
2
using System.Threading;
3
4
namespace TestLab.System.Threading
5
{
6
//在遇到線程類問題的時候,我們需要注意:
7
//a線程在執(zhí)行“代碼中連續(xù)的語句”a1、a2時,并不代表他們在實際執(zhí)行時也是連續(xù)了(也許是連續(xù)的也許不是)
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}創(chuàng)建新的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}操作完畢,現(xiàn)在的數(shù)據(jù)值:{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} 已經(jīng)離開操作------{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} 已經(jīng)離開操作------{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} 已經(jīng)離開操作------{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} 已經(jīng)離開操作------{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}創(chuàng)建新的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}執(zhí)行LowLevel1Help.FightHelp2():{0}", this._name, DateTime.Now);
167
}
168
}
169
//這個方法對象的是LowLevel1.FightOver3()
170
//當有線程執(zhí)行LowLevel1.FightOver2()時,執(zhí)行這個方法的對象被鎖了,需要在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}執(zhí)行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線程在執(zhí)行“代碼中連續(xù)的語句”a1、a2時,并不代表他們在實際執(zhí)行時也是連續(xù)了(也許是連續(xù)的也許不是)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}創(chuàng)建新的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}操作完畢,現(xiàn)在的數(shù)據(jù)值:{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} 已經(jīng)離開操作------{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} 已經(jīng)離開操作------{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} 已經(jīng)離開操作------{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} 已經(jīng)離開操作------{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}創(chuàng)建新的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}執(zhí)行LowLevel1Help.FightHelp2():{0}", this._name, DateTime.Now);167
}168
}169
//這個方法對象的是LowLevel1.FightOver3()170
//當有線程執(zhí)行LowLevel1.FightOver2()時,執(zhí)行這個方法的對象被鎖了,需要在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}執(zhí)行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


浙公網(wǎng)安備 33010602011771號