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