学习笔记之线程
一、线程的本质
线程是程序的中的执行流,每个线程都有自己的专有寄存器(栈指针,程序计数器等),但代码是共享的,即不同的线程可以执行相同的函数。
线程本质:是一个为CPU执行准备的数据结构,也就是说,他负责告诉CPU要做什么事,并且为cpu提供这个事情的资源;
每个线程经过线程调度器,来让cpu执行Windows的线程只有七个优先级。所以调度器负责为CPU分配要执行的线程,以及线程执行时间,到达时间后,强制停止执行。
二、线程的安全性
cpu的执行速度太快了,所以为了快速访问,cpu不会直接读取线程的 工作缓存 ,而是将 工作缓存的内容读取到,cpu的耳机缓存中,以便快速访问。
而当cpu操作 不同线程,而不同线程会操作同一段数据,如果当cpu执行完某一个线程而未将数据返回到工作缓存时,再次执行下一线程时,此时线程中工作缓存数据未写回,产生线程安全问题。

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Runtime.CompilerServices; 5 using System.Text; 6 using System.Threading; 7 8 namespace ThreadTest 9 { 10 class ThreadTest 11 { 12 public object locker = new object(); 13 int count = 100; 14 public void Sell() 15 { 16 //Console.WriteLine("当前进入的线程:" + System.Threading.Thread.CurrentThread.Name); 17 while (count > 0) 18 { 19 lock (locker)//不同线程执行这个代码时只要确保是同一个对象就可以了,如: this.GetType() / static变量 / 相同实例变量 20 { 21 count--; 22 Console.WriteLine(System.Threading.Thread.CurrentThread.Name + ",剩{0}张~!", count); 23 } 24 } 25 } 26 27 #region 1.0测试 实例方法里的锁 28 /// <summary> 29 /// 1.0测试 实例方法里的锁 30 /// </summary> 31 /// <param name="oLoker"></param> 32 public void TestSellMany() 33 { 34 ThreadTest tt = new ThreadTest(); 35 Thread t1 = new Thread(tt.Sell); 36 t1.Name = "t1"; 37 t1.IsBackground = true; 38 39 Thread t2 = new Thread(tt.Sell); 40 t2.Name = "t2"; 41 t2.IsBackground = true; 42 43 t1.Start(); 44 t2.Start(); 45 } 46 #endregion 47 //---------------------------------------------------------------- 48 49 static int countStatic = 100; 50 public static object lockerStatic = new object(); 51 public static void SellStatic(object oLoker) 52 { 53 while (countStatic > 0) 54 { 55 lock (oLoker)//不同线程执行这个代码时只要确保是同一个对象就可以了,如: this.GetType() / static变量 / 相同实例变量 56 { 57 countStatic--; 58 Console.WriteLine(System.Threading.Thread.CurrentThread.Name + ",剩{0}张~!", countStatic); 59 } 60 } 61 } 62 63 #region 2.0 测试 静态方法里的锁 64 /// <summary> 65 /// 测试 静态方法里的锁 66 /// </summary> 67 public void TestSellManyStatic() 68 { 69 ThreadTest tt = new ThreadTest(); 70 Thread t1 = new Thread(SellStatic); 71 t1.Name = "t1"; 72 t1.IsBackground = true; 73 74 Thread t2 = new Thread(SellStatic); 75 t2.Name = "t2"; 76 t2.IsBackground = true; 77 78 object lok = new object(); 79 t1.Start(lok); 80 t2.Start(lok); 81 } 82 #endregion 83 //---------------------------------------------------------------- 84 public void SellByMonitor() 85 { 86 while (countStatic > 0) 87 { 88 bool isGetLoker = false; 89 try 90 { 91 Monitor.Enter(locker, ref isGetLoker);//尝试获取锁,如果获取成功,isGetLoker=true,否则=false 92 countStatic--; 93 Console.WriteLine(System.Threading.Thread.CurrentThread.Name + ",剩{0}张~!", countStatic); 94 } 95 catch (Exception ex) 96 { 97 throw ex; 98 } 99 finally 100 { 101 if (isGetLoker)//如果有锁,就解锁;否则,没有锁,就不存在 解锁! 102 { 103 Monitor.Exit(locker); 104 } 105 } 106 } 107 } 108 #region 3.0 测试 Monitor 109 /// <summary> 110 /// 3.0 测试 Monitor 111 /// </summary> 112 public static void TestMonitor() 113 { 114 ThreadTest tt = new ThreadTest(); 115 Thread t1 = new Thread(tt.SellByMonitor); 116 t1.Name = "t1"; 117 t1.IsBackground = true; 118 119 Thread t2 = new Thread(tt.SellByMonitor); 120 t2.Name = "t2"; 121 t2.IsBackground = true; 122 123 t1.Start(); 124 t2.Start(); 125 } 126 #endregion 127 128 int forNum = 0; 129 public void PrintNum(int num) 130 { 131 Console.WriteLine(System.Threading.Thread.CurrentThread.Name+",哈哈哈~~~"); 132 Console.WriteLine(num); 133 } 134 135 //同步方法 特性 136 [MethodImpl(MethodImplOptions.Synchronized)] 137 public void MethodLock() 138 { 139 for (; forNum < 100; forNum++) 140 { 141 PrintNum(forNum); 142 } 143 } 144 145 #region 4.0 测试同步方法 146 //测试同步方法 147 public static void TestMothodLock() 148 { 149 ThreadTest tt = new ThreadTest(); 150 Thread t1 = new Thread(tt.MethodLock); 151 t1.Name = "t1"; 152 t1.IsBackground = true; 153 154 Thread t2 = new Thread(tt.MethodLock); 155 t2.Name = "t2"; 156 t2.IsBackground = true; 157 158 t1.Start(); 159 t2.Start(); 160 } 161 #endregion 162 //------------------------------------------------------------------------- 163 static object locker1 = new object(); 164 static object locker2 = new object(); 165 166 #region 5.0测试死锁 167 //5.0测试死锁 168 public static void TestDeadLock() 169 { 170 new Thread(() => 171 { 172 Console.WriteLine("线程1开始执行"); 173 lock (locker1) //获取锁locker1 174 { 175 Console.WriteLine("线程1获取锁1"); 176 Thread.Sleep(1000); 177 lock (locker2) //尝试获取locker2 178 { 179 Console.WriteLine("线程1获取锁2"); 180 } 181 } 182 }).Start(); 183 184 new Thread(() => 185 { 186 Console.WriteLine("线程2开始执行"); 187 lock (locker2) //获取锁locker2 188 { 189 Console.WriteLine("线程2获取锁2"); 190 Thread.Sleep(1000); 191 lock (locker1) //尝试获取locker1 192 { 193 Console.WriteLine("线程2获取锁1"); 194 } 195 } 196 }).Start(); 197 } 198 #endregion 199 //------------------------------------------------------------------------- 200 #region 6.0 测试 线程通信 201 /// <summary> 202 /// 6.0 测试 线程通信 203 /// </summary> 204 public static void TestProCus() 205 { 206 Dog d = new Dog(); 207 Productor p = new Productor(d); 208 Customer c = new Customer(d); 209 210 Thread trhPro = new Thread(p.ProductDog); 211 trhPro.IsBackground = true; 212 trhPro.Name = "t1"; 213 214 Thread trhCus = new Thread(c.ShowDogInfo); 215 trhCus.IsBackground = true; 216 trhCus.Name = "t2"; 217 218 trhPro.Start(); 219 trhCus.Start(); 220 Console.ReadLine(); 221 trhPro.Abort(); 222 trhCus.Abort(); 223 } 224 #endregion 225 //------------------------------------------------------------------------- 226 227 public static void Mother() 228 { 229 Console.WriteLine("买菜~~~"); 230 Console.WriteLine("切菜~~~"); 231 Console.WriteLine("做菜~~~"); 232 Console.WriteLine("做饭~~~判断是否有米,发现木有米勒,就叫儿子去买米......"); 233 Thread thrSon = new Thread(Son); 234 thrSon.IsBackground = true; 235 thrSon.Start(); 236 thrSon.Join();//强制阻断其他线程执行,先执行当前线程thrSon 237 Console.WriteLine("儿子买米回来了~~~"); 238 Console.WriteLine("淘米~~~"); 239 Console.WriteLine("煮饭~~~"); 240 Console.WriteLine("吃饭~~~"); 241 } 242 243 public static void Son() 244 { 245 Console.WriteLine("妈妈叫我去买米~~~"); 246 Console.WriteLine("买米哦~~~"); 247 for (int i = 0; i < 5; i++) 248 { 249 System.Threading.Thread.Sleep(500); 250 Console.WriteLine("{0}秒钟......",i); 251 } 252 Console.WriteLine("买好米勒,回家~~~!"); 253 } 254 255 public static void TestJoin() 256 { 257 Thread thrMother = new Thread(Mother); 258 thrMother.IsBackground = true; 259 thrMother.Start(); 260 } 261 262 public static void Main(string[] ar) 263 { 264 //TicketSeller t1 = new TicketSeller("1台"); 265 //TicketSeller t2 = new TicketSeller("2台"); 266 TestJoin(); 267 Console.ReadLine(); 268 } 269 270 } 271 272 /// <summary> 273 /// 产品 274 /// </summary> 275 public class Dog 276 { 277 public static object lockCommunicate = new object(); 278 279 public string name; 280 public int age; 281 } 282 283 /// <summary> 284 /// 生产者 285 /// </summary> 286 public class Productor 287 { 288 Dog myDog; 289 public Productor(Dog d) 290 { 291 myDog = d; 292 } 293 294 bool type = true; 295 public void ProductDog() 296 { 297 while (true) 298 { 299 lock (Dog.lockCommunicate) 300 { 301 if (type) 302 { 303 myDog.name = "Ruiky"; 304 myDog.age = 2; 305 } 306 else 307 { 308 myDog.name = "瑞奇"; 309 myDog.age = 1; 310 } 311 type = !type; 312 Monitor.Pulse(Dog.lockCommunicate); 313 Monitor.Wait(Dog.lockCommunicate); 314 } 315 } 316 } 317 } 318 319 public class Customer 320 { 321 Dog myDog; 322 public Customer(Dog d) 323 { 324 myDog = d; 325 } 326 327 public void ShowDogInfo() 328 { 329 while (true) 330 { 331 lock (Dog.lockCommunicate) 332 { 333 Console.WriteLine("我是{0},年龄{1}", myDog.name, myDog.age); 334 Monitor.Pulse(Dog.lockCommunicate); 335 Monitor.PulseAll(Dog.lockCommunicate); 336 Monitor.Wait(Dog.lockCommunicate); 337 } 338 } 339 } 340 } 341 342 public class TicketSeller 343 { 344 public static int count = 100; 345 public static object locker = new object(); 346 347 public TicketSeller(string taiName) 348 { 349 Thread t2 = new Thread(Sell); 350 t2.Name = taiName;// "2号台"; 351 t2.IsBackground = true; 352 t2.Start(); 353 } 354 355 public void Sell() 356 { 357 while (count > 0) 358 { 359 lock (this) 360 { 361 TicketSeller.count--; 362 Console.WriteLine(System.Threading.Thread.CurrentThread.Name + ",剩{0}张~!", count); 363 } 364 } 365 } 366 367 public void Sell2() 368 { 369 lock (locker) 370 { 371 372 } 373 } 374 } 375 }