关于“GUI 博士的忠告:切勿锁定类型对象!”的实验
1using System;
2using System.Threading;
3
4namespace 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
2using System.Threading;
3
4namespace 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