var Buffer int occupiedCount Proc Produce(var x) { Monitor.Enter(Buffer) if(occupiedCount == 1) { //no more space // Wait for Consumer to Consume Data and Decrement occupiedCount Monitor.Wait(Buffer) } Buffer = x //Incrementing occupiedCount means that the data has beed Produced and //ready to read occupiedCount = occupiedCount + 1 //Tells the waiting Consumer thread -if there is one- that there are a // change in Buffer Monitor.Pulse(Buffer) Monitor.Exit(Buffer) //Now The Consumer Thread can Access Buffer } Proc Consumer(var x) { int BufferCopy Monitor.Enter(Buffer) if(occupiedCount == 0) { //no Data to read //Wait for Producer to Produce Data and Increment occupiedCount Monitor.Wait(Buffer) } BufferCopy = Buffer //Save Original Buffer Data //Decrementing occupiedCount means that the data has beed consumed occupiedCount = occupiedCount - 1 //Tells the waiting Producer thread -if there is one- that there are a // change in Buffer Monitor.Pulse(Buffer) Monitor.Exit(Buffer) return BufferCopy }
public class Producer { //code.. public void Produce() { //Controller method which will passed to the Thread Constructor } }
public class Consumer { //code.. public void Consume() { //Controller method which will passed to the Thread Constructor } }
Thread m_ProducerThread = new Thread(new ThreadStart(producer.Produce)); m_ProducerThread.Name = "Producer"; Thread m_ConsumerThread = new Thread(new ThreadStart(consumer.Consume)); m_ConsumerThread.Name = "Consumer";
private int intBuffer = -1; //Shared Object public HoldResourceSynchronized() { } public int Buffer { get { //just like the Proc Consumer in the Algorithm //lock this Object while getting value from buffer, Consumer Monitor.Enter(this); //if there is no data to read, Then Wait [WaitSleepJoin State] if(intOccupiedBuffCount == 0) { //do some output registering here Monitor.Wait(this); } //Just consumed a value, so decrement number of occupied buffers --intOccupiedBuffCount; //return waiting thread (if there is one) to Started State Monitor.Pulse(this); /* * Get Copy of intBuffer releasing lock. * It is possible that the producer could be assigned the processor immediately after the Monitor * is released & before the the return statment executes, In this case the producer would assign a * new value to the intBuffer before return statement returns the value to the consumer. * Making a copy of the Original Buffer solve this issue. */ int intBufferCopy = intBuffer; //Release Object Monitor.Exit(this); return intBufferCopy; } set { //just like the Proc Producer in the Algorithm //Lock this object while setting value in buffer //Producer Monitor.Enter(this); //if there are no empty location, Then Wait [WaitSleepJoin State] if(intOccupiedBuffCount == 1) { //do some output registering here Monitor.Wait(this); } intBuffer = value; //Just Produced a value, so increment number of occupied buffers ++intOccupiedBuffCount; //return waiting thread (if there is one) to Started State Monitor.Pulse(this); Monitor.Exit(this); } }
Monitor.Enter(This); //Critical section code... Monitor.Exit(This); are Equal to this: lock(this) { //Critical section code... }
public void Produce() { //Produce integers from 1 to 4 for(int i=1; i<=4; i++) { //m_randSleepTime is Random object to provide delay randomly //We don't know who is faster Producer or consumer //the same is in the Consumer Consume Method Thread.Sleep(m_randSleepTime.Next(1,3000)); //m_sharedResource is HoldResourceSynchronized reference passed //to Producer Constructor //the same object passed to Consumer Constructor m_SharedResource.Buffer = i; i++; } //output messages here to display the end of the thread. } public void Consume() { int sum = 0; //Consume the 4 integers objects produced by Producer for(int i=1; i<=4; i++) { Thread.Sleep(m_randSleepTime.Next(1,3000)); sum += m_SharedResource.Buffer; } //output messages here to display the end of the thread. }
public frmProducerConsumer() { InitializeComponent(); Random rand = new Random(); //OutputMessage is a public delegate, I use it to display output //in text boxs // I use it in case I want to change the output control, all I // need to do then is update the method OutMessageHandle. m_SharedRes = new HoldResourceSynchronized( new OutputMessage(OutMessageHandle)); Producer producer = new Producer(m_SharedRes,rand, new OutputMessage(OutMessageHandle)); Consumer consumer = new Consumer(m_SharedRes,rand, new OutputMessage(OutMessageHandle)); m_ProducerThread = new Thread(new ThreadStart(producer.Produce)); m_ProducerThread.Name = "Producer"; m_ConsumerThread = new Thread(new ThreadStart(consumer.Consume)); m_ConsumerThread.Name = "Consumer"; }
private void btnStart_Click(object sender, System.EventArgs e) { m_ProducerThread.Start(); m_ConsumerThread.Start(); btnStart.Enabled = false; }
Build Your Own ASP.NET Website Using C# & VB.NET