// 多个生产者和多个消费者,能生产n个产品的情况using System; using System.Threading;public class HoldIntegerSynchronized{private int[] buffer; //缓冲区private int occupiedBufferCount = 0;private int readPosition = 0 , writePosition = 0;//下一个读到的位置和写到的位置public HoldIntegerSynchronized(int capacity){buffer = new int[capacity];}public int BufferSize{get{return buffer.Length;}}public int Buffer{get{int bufferCopy;// 加锁lock(this){while(occupiedBufferCount == 0){ //多个消费者,所以此处改用whileConsole.WriteLine(Thread.CurrentThread.Name + " tries to read. ");DisplayState("Buffer Empty. " + Thread.CurrentThread.Name + " waits.");Monitor.Wait(this); // 为临界区之外等待的生产者放行,让他来"生产"// 一直到生产者生产结束,调用了Monitor.PauseAll()// 才能继续执行下去,此时,消费者自动重新获得this的锁 }--occupiedBufferCount;bufferCopy = buffer[readPosition];readPosition = (readPosition + 1) % buffer.Length; DisplayState(Thread.CurrentThread.Name + " reads " + bufferCopy);// 通知,让等待的 生产者线程 进入Started状态,如果生产者处于临界区之外,这句话执行完后他仍然在临界区之外Monitor.PulseAll(this);// 释放锁}//lockreturn bufferCopy;}set{// 加锁lock(this){while(occupiedBufferCount == buffer.Length){Console.WriteLine(Thread.CurrentThread.Name + " tries to write. ");DisplayState("Buffer Full. " + Thread.CurrentThread.Name + " waits.");Monitor.Wait(this); // 为临界区之外等待消费者放行,让他来"消费"// 一直到消费者调用了Monitor.Pause()// 才能继续执行下去,此时,生产者自动重新获得this的锁 }buffer[writePosition] = value;++occupiedBufferCount; writePosition = (writePosition + 1) % buffer.Length;DisplayState(Thread.CurrentThread.Name + " writes " + value);// 通知,让Wait状态的 消费者 进入Started状态,如果消费者处于临界区之外,这句话执行完后他仍然在临界区之外Monitor.PulseAll(this);// 释放锁 }}}public void DisplayState(string operation){Console.Write("{0,-35}",operation);for(int i = 0; i < BufferSize; i++ ){int a = readPosition;int b = writePosition;if( a <= i && i < b) {Console.Write("{0,-9}",buffer[i]);}else if( b < a && !( b <= i && i < a ) ){Console.Write("{0,-9}",buffer[i]);}else if( occupiedBufferCount == BufferSize){Console.Write("{0,-9}",buffer[i]);}else{Console.Write("{0,-9}","");}}Console.WriteLine("{0}/r/n",occupiedBufferCount);} }class Producer{private HoldIntegerSynchronized sharedLocation;private Random randomSleepTime;public Producer(HoldIntegerSynchronized shared,Random random){sharedLocation = shared;randomSleepTime = random;}public void Produce(){for (int count=0; count<3; count++) {Thread.Sleep(randomSleepTime.Next(1,2000));sharedLocation.Buffer = randomSleepTime.Next(5,10);}Console.WriteLine(Thread.CurrentThread.Name + " done producing./r/nTerminating " + Thread.CurrentThread.Name + "./r/n");} }class Consumer{private HoldIntegerSynchronized sharedLocation;private Random randomSleepTime;public Consumer(HoldIntegerSynchronized shared,Random random){sharedLocation = shared;randomSleepTime = random;}public void Consume(){int sum = 0;for (int count=0; count<4; count++) {Thread.Sleep(randomSleepTime.Next(1,2000));sum += sharedLocation.Buffer;}Console.WriteLine(Thread.CurrentThread.Name + " read values totaling:" + sum + "/r/nTerminating " + Thread.CurrentThread.Name + ".");} }class SharedCell{static void Main(string[] args){HoldIntegerSynchronized holdInteger = new HoldIntegerSynchronized(5);Random random = new Random();Thread[] producerThreads = new Thread[4];Thread[] consumerThreads = new Thread[3];Console.Write("{0,-35}","Operation");for(int i = 0;i < holdInteger.BufferSize;i++){Console.Write("{0,-9}","Elem " + i);}Console.WriteLine("Occupied Count/r/n");for(int i = 0; i < producerThreads.Length;i++){Producer producer = new Producer(holdInteger,random);producerThreads[i] = new Thread(new ThreadStart(producer.Produce));producerThreads[i].Name = "Producer No." + i;}for(int i = 0; i < consumerThreads.Length;i++){Consumer consumer = new Consumer(holdInteger,random);consumerThreads[i] = new Thread(new ThreadStart(consumer.Consume));consumerThreads[i].Name = "Consumer No." + i;}for(int i = 0; i < producerThreads.Length;i++){producerThreads[i].Start();}for(int i = 0; i < consumerThreads.Length;i++){consumerThreads[i].Start();}} }