关于“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
posted @ 2009-01-13 22:15  Miser  阅读(380)  评论(0编辑  收藏  举报