我们讲述了多线程编程过程中,一种限制多个线程对资源的同时访问的技术——锁。
小明同学,上周未和家人出去游玩去了。刚学了锁的用法,小明终于完善的模拟出了早餐店的流水线,所以他游玩很开心。但是回家的路上,却遇到了烦心事!
由于天气很好,小明一家人游玩到了天黑才驱车回家。正值交通拥堵的时候,在他们即将行进到一个环岛的时候,交通完全堵死了。
传说中的堵死
小明在车上看着道路资源被无限的占用着,联想到多线程编程中的锁:要是限制一下进入环岛的车辆的数量,是不是就不会出现这种无限的堵死在状态呢!
由于车辆太多,已经进入环岛的车辆,出环岛的路被堵死,无法出去,无法释放占用的道路资源。想要进入环岛的车辆,却又因为无法进入环岛而又一直占用着环岛的出口。这不就是个死循环嘛!
在堵了一个小时之后,小明一家人终于走过了这个环岛,不一会就到家了。
死锁演示
聪明的小明,直觉告诉他,在多线程中,也可能会出现这种现象。于是他用两个锁对象,模拟了环岛堵死的场景:
class Program { static long uniqueRes = 0; // 唯一资源 // 锁对象 static object roadOut = new object(); static object roadIn = new object(); static void EnterCircle() { lock (roadIn) { // 模拟堵在了入口 for (int i = 0; i < 10000; i++) { uniqueRes += 1; } lock (roadOut) { // 模拟堵在了出口 for (int i = 0; i < 10000; i++) { uniqueRes -= 1; } } } } static void ExitCircle() { // 将资源锁上 lock (roadOut) { // 模拟堵在了出口处 while (true) { uniqueRes -= 1; } } } static void Main(string[] args) { Console.WriteLine("Hello Thread Dead Locker!"); var t1 = new Thread(EnterCircle); var t2 = new Thread(ExitCircle); t1.Start(); t2.Start(); t1.Join(); t2.Join(); Console.WriteLine($"sum: {uniqueRes}"); Console.ReadKey(); } }
运行结果如下:
程序无法结束