/*
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 SynchronizedBuffer
{
private int buffer = -1;
private int occupiedBufferCount = 0;
public int Buffer
{
get
{
Monitor.Enter( this );
if ( occupiedBufferCount == 0 )
{
Console.WriteLine(Thread.CurrentThread.Name + " tries to read." );
DisplayState( "Buffer empty. " +Thread.CurrentThread.Name + " waits." );
Monitor.Wait( this );
}
--occupiedBufferCount;
DisplayState( Thread.CurrentThread.Name + " reads " + buffer );
Monitor.Pulse( this );
int bufferCopy = buffer;
Monitor.Exit( this );
return bufferCopy;
}
set
{
Monitor.Enter( this );
if ( occupiedBufferCount == 1 )
{
Console.WriteLine(Thread.CurrentThread.Name + " tries to write." );
DisplayState( "Buffer full. " + Thread.CurrentThread.Name + " waits." );
Monitor.Wait( this );
}
buffer = value;
++occupiedBufferCount;
DisplayState( Thread.CurrentThread.Name + " writes " + buffer );
Monitor.Pulse( this );
Monitor.Exit( this );
}
}
public void DisplayState( string operation )
{
Console.WriteLine( "{0,-35}{1,-9}{2}\n",operation, buffer, occupiedBufferCount );
}
static void Main( string[] args )
{
SynchronizedBuffer shared = new SynchronizedBuffer();
Random random = new Random();
Console.WriteLine( "{0,-35}{1,-9}{2}\n","Operation", "Buffer", "Occupied Count" );
shared.DisplayState( "Initial state" );
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();
}
}
public class Consumer
{
private SynchronizedBuffer sharedLocation;
private Random randomSleepTime;
public Consumer( SynchronizedBuffer 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, 1001 ) );
sum += sharedLocation.Buffer;
}
Console.WriteLine("{0} read values totaling: {1}.\nTerminating {0}.",Thread.CurrentThread.Name, sum );
}
}
public class Producer
{
private SynchronizedBuffer sharedLocation;
private Random randomSleepTime;
public Producer( SynchronizedBuffer shared, Random random )
{
sharedLocation = shared;
randomSleepTime = random;
}
public void Produce()
{
for ( int count = 1; count <= 10; count++ )
{
Thread.Sleep( randomSleepTime.Next( 1, 1001 ) );
sharedLocation.Buffer = count;
}
Console.WriteLine( "{0} done producing.\nTerminating {0}.",Thread.CurrentThread.Name );
}
}