Producer and consumer with a Circular Buffer : Producer Consumer « Thread « C# / C Sharp






Producer and consumer with a Circular Buffer

Producer and consumer with a Circular Buffer
/*
Code revised from Book published by 
(C) Copyright 1992-2006 by Deitel & Associates, Inc. and
Pearson Education, Inc. All Rights Reserved.  

*/
using System;
using System.Threading;

public class Producer 
{
   private CircularBuffer sharedLocation;
   private Random randomSleepTime;

   public Producer( CircularBuffer shared, Random random )
   {
      sharedLocation = shared;
      randomSleepTime = random;
   }
   public void Produce()
   {
      for ( int count = 1; count <= 10; count++ ) 
      {
         Thread.Sleep( randomSleepTime.Next( 1, 3001 ) );
         sharedLocation.Buffer = count; 
      } 
      Console.WriteLine( "{0} done producing.\nTerminating {0}.", Thread.CurrentThread.Name );
   }
}

public class Consumer
{
   private CircularBuffer sharedLocation;
   private Random randomSleepTime;

   public Consumer( CircularBuffer shared, Random random )
   {
      sharedLocation = shared;
      randomSleepTime = random;
   }
   public void Consume()
   {
      int sum = 0;

      for ( int count = 1; count <= 10; count++ )
      {
         Thread.Sleep( randomSleepTime.Next( 1, 3001 ) );
         sum += sharedLocation.Buffer;
      }

      Console.WriteLine("{0} read values totaling: {1}.\nTerminating {0}.",
         Thread.CurrentThread.Name, sum );
   }
}


public class CircularBuffer
{
   private int[] buffers = { -1, -1, -1 };

   private int occupiedBufferCount = 0;

   private int readLocation = 0; 
   private int writeLocation = 0;
   
   public int Buffer
   {
      get
      {
         lock ( this )
         {
            if ( occupiedBufferCount == 0 )
            {
               Console.Write( "\nAll buffers empty. {0} waits.",Thread.CurrentThread.Name );
               Monitor.Wait( this );
            } 
            int readValue = buffers[ readLocation ];

            Console.Write( "\n{0} reads {1} ",Thread.CurrentThread.Name, buffers[ readLocation ] );

            --occupiedBufferCount;

            readLocation = ( readLocation + 1 ) % buffers.Length;
            Console.Write( CreateStateOutput() );
            Monitor.Pulse( this );

            return readValue;
         }
      }
      set
      {
         lock ( this )
         {
            if ( occupiedBufferCount == buffers.Length )
            {
               Console.Write( "\nAll buffers full. {0} waits.",Thread.CurrentThread.Name );
               Monitor.Wait( this );
            }
            buffers[ writeLocation ] = value;

            Console.Write( "\n{0} writes {1} ",Thread.CurrentThread.Name, buffers[ writeLocation ] );

            ++occupiedBufferCount;
            writeLocation = ( writeLocation + 1 ) % buffers.Length;
            Console.Write( CreateStateOutput() );
            Monitor.Pulse( this );
         }
      }
   }

   public string CreateStateOutput()
   {
      string output = "(buffers occupied: " + occupiedBufferCount + ")\nbuffers: ";

      for ( int i = 0; i < buffers.Length; i++ )
         output += " " + string.Format( "{0,2}", buffers[ i ] ) + "  ";

      output += "\n";
      output += "         ";

      for ( int i = 0; i < buffers.Length; i++ )
         output += "---- ";

      output += "\n";

      output += "         ";

      for ( int i = 0; i < buffers.Length; i++ ) 
      {
         if ( i == writeLocation && 
            writeLocation == readLocation ) 
            output += " WR  ";
         else if ( i == writeLocation )
            output += " W   ";
         else if  ( i == readLocation ) 
            output += "  R  ";
         else
            output += "     ";
      }

      output += "\n";
      return output;
   }

   static void Main( string[] args )
   {
      CircularBuffer shared = new CircularBuffer();

      Random random = new Random();

      Console.Write( shared.CreateStateOutput() );

      Producer producer = new Producer( shared, random );
      Consumer consumer = new Consumer( shared, random );

      Thread producerThread = new Thread( new ThreadStart( producer.Produce ) );
      producerThread.Name = "Producer";

      Thread consumerThread = new Thread( new ThreadStart( consumer.Consume ) );
      consumerThread.Name = "Consumer";

      producerThread.Start();
      consumerThread.Start();
   }    
} 
           
       








Related examples in the same category

1.Producer and comsumer in a synchronized bufferProducer and comsumer in a synchronized buffer
2.Uses Wait and Pulse to enable producer and consumer threads to cooperate in using a buffer