C# Thread 多线程 Monitor 锁 Producer And Consumer 生产者和消费者 经典模型
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading; 6 using System.Threading.Tasks; 7 8 namespace ConsoleApplication1 9 { 10 //说明: 11 //2个线程启动的时候抢夺CPU资源,于是产生了2种线程执行先后顺序的情况,不过好在我们 12 //的程序能控制即使消费者优先抢到了CPU资源也要阻塞,直到生产者生产出1个_count值, 13 // 14 //以下仅仅说明该程序2个线程之间状态的转换,对于高手,请绕过说明。 15 //1. Producer(生产者先获取_locker) 16 // Producer获取锁 17 // Consumer进入就绪队列 18 // Producer进入等待队列,释放锁 19 // Consumer获取锁 20 // Producer进入就绪队列 21 // Consumer进入等待队列,释放锁 22 // _count加1 23 // Console打印“生产者” 24 // Consumer进入就绪队列 25 // Producer释放锁 26 // Console打印“消费者” 27 // Producer进入就绪队列 28 // Consumer释放锁 29 // Producer再次进入for循环 30 // 31 // 32 //2. Consumer(消费者先获取_locker) 33 // Consumer获取锁 34 // Producer进入就绪队列 35 // Consumer进入等待队列,释放锁 36 // Producer获取锁 37 // Consumer进入就绪队列 38 // Producer进入等待队列,释放锁 39 // Producer进入就绪队列 40 // Consumer释放锁 41 // _count加1 42 // Console打印“生产者” 43 // Consumer进入就绪队列 44 // Producer释放锁 45 // Consumer获取锁 46 // Producer进入就绪队列 47 // Consumer进入等待队列,释放锁 48 // Producer再次进入for循环 49 // 50 //注:本段代码摘自网络,原出处: 51 //http://www.51testing.com/html/32/367232-857405.html 52 class ThreadProcConsume 53 { 54 private int _count; 55 private object _locker = new object(); 56 57 58 public ThreadProcConsume(int _count) 59 { 60 this._count = _count; 61 } 62 63 public void Run() 64 { 65 Thread tProducer = new Thread(new ThreadStart(Producer)); 66 Thread tConsumer = new Thread(new ThreadStart(Consumer)); 67 68 tProducer.Start(); 69 tConsumer.Start(); 70 } 71 72 public void Producer() 73 { 74 for (int i = 0; i < 10; i++) 75 { 76 try 77 { 78 //持有锁,进入线程,其他线程阻塞 79 Monitor.Enter(_locker); 80 //将等待队列中的线程添加到就绪队列 81 Monitor.Pulse(_locker); 82 //释放锁_locker, 将线程自身添加到等待队列 83 Monitor.Wait(_locker); 84 85 this._count++; 86 87 Console.WriteLine("生产者 " + _count.ToString()); 88 89 Monitor.Pulse(_locker); 90 } 91 finally 92 { 93 //仅释放锁 94 Monitor.Exit(_locker); 95 } 96 } 97 } 98 99 public void Consumer() 100 { 101 try 102 { 103 Monitor.Enter(_locker); 104 Monitor.Pulse(_locker); 105 106 while (Monitor.Wait(_locker)) 107 { 108 if (this._count != 0) 109 { 110 Console.WriteLine("消费者 " + this._count.ToString()); 111 } 112 Monitor.Pulse(_locker); 113 if (this._count == 10) 114 { 115 return; 116 } 117 } 118 } 119 finally 120 { 121 Monitor.Exit(_locker); 122 } 123 } 124 } 125 }
客户端代码:
1 using System; 2 3 namespace ConsoleApplication1 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 ThreadProcConsume tp = new ThreadProcConsume(0); 10 tp.Run(); 11 12 Console.ReadKey(); 13 } 14 } 15 }