I am trying to create a program that has two threads (producer and consumer) manipulating the same object (an integer). There will be two loops running, the first has the producer write a number (it goes 1,2,3,4) and the consumer then reads it and totals it. The second loop I need to do must have the producer write A,B,C,D and then have the consumer read it, and I'm having trouble creating a loops similar to this
for ( int count = 1; count <= 4; count++ )
But instead of 1,2,3,4 have it use A,B,C,D. Does anyone have an idea of how to accomplish that? This is what I have so far, the code is a bit jumbled but please bare with me. Thanks!
// In-Exercise 2: Synchronized2.cs
// (1) Extend the Synchronized example by adding a SharedString class.
// (2) Pass a SharedString object to Consumer and Producer constructor method calls.
// (3) Consumer object writes "A", "B", "C" and "D" into a SharedMsg object.
// (4) Producer object reads "A", "B", "C" and "D" in order from the SharedMsg object.
using
System;
using
System.Threading;
//
namespace
Synchronized2
{
// this class synchronizes access to an integer
public class SharedAndSynchronized
{
// buffer shared by producer and consumer threads
private int buffer = -1;
// bufferFull checks if buffer is full
private bool bufferFull = false;
public void SetBuffer(int v)
{
// Producer try acquiring lock for this object
Monitor.Enter( this );
// if buffer is full (the previous value has not be read),
// ask this Producer thread to wait on this shared object
if ( bufferFull == true )
{
Console.WriteLine( Thread.CurrentThread.Name + " tries to write again." );
DisplayState(
"Buffer full, " + Thread.CurrentThread.Name + " waits....." );
Monitor.Wait( this );
}
// if buffer is empty, write a new value v
buffer = v;
// set bufferFull to true to indicate a new value is available
bufferFull =
true;
DisplayState(
Thread.CurrentThread.Name + " writes " + buffer );
// tell waiting Consumer thread (if there is one) to become ready to execute
Monitor.Pulse( this );
// release lock on this object
Monitor.Exit( this );
}
// end SetBuffer
public int GetBuffer()
{
// Consumer try obtaining lock on this object
Monitor.Enter( this );
// if no data to read, ask this Consumer thread to wait on this shared object
if ( bufferFull == false )
{
Console.WriteLine( Thread.CurrentThread.Name + " tries to read." );
DisplayState(
"Buffer empty, " + Thread.CurrentThread.Name + " waits....." );
Monitor.Wait( this );
}
// if there is data to read, set bufferFull to false before reading
bufferFull =
false;
DisplayState(
"*" + Thread.CurrentThread.Name + " reads " + buffer + "*");
// tell waiting Producer thread (if there is one) to become ready to execute
Monitor.Pulse( this );
// release lock on this object
Monitor.Exit( this );
// finally actually read the buffer data
return buffer;
}
// end GetBuffer
// display current operation and buffer state
public void DisplayState( string operation )
{
Console.WriteLine( "{0,-35}{1,-9}{2}\n", operation, buffer, bufferFull );
}
}
// end class SharedAndSynchronized
//-----------------------------------------------------
// this SharedString class synchronizes access to a string
public class SharedString// write the set and get methods, you can copy and paste the get and set buffer methods.
//complete this part below, the shared string part. you can copy and past and modify
//4 lines of code on get and set. modify producer method to get the shared string object.
//in producer method, call the switch the reading and writing between producer and consumer.
{
// msg shared by producer and consumer threads??
// msgFull checks if msg is full??
public void SetMsg(string s) //??
{
// Producer try acquiring lock for this object
Monitor.Enter(this);
// if buffer is full (the previous value has not be read),
// ask this Producer thread to wait on this shared object
if (bufferFull == true)
{
Console.WriteLine(Thread.CurrentThread.Name + " tries to write again.");
DisplayState(
"Buffer full, " + Thread.CurrentThread.Name + " waits.....");
Monitor.Wait(this);
}
// if buffer is empty, write a new value v
buffer = v;
// set bufferFull to true to indicate a new value is available
bufferFull =
true;
DisplayState(
Thread.CurrentThread.Name + " writes " + buffer);
// tell waiting Consumer thread (if there is one) to become ready to execute
Monitor.Pulse(this);
// release lock on this object
Monitor.Exit(this);
}
// end SetMsg
public string GetMsg() //??
{
// Consumer try obtaining lock on this object
Monitor.Enter(this);
// if no data to read, ask this Consumer thread to wait on this shared object
if (bufferFull == false)
{
Console.WriteLine(Thread.CurrentThread.Name + " tries to read.");
DisplayState(
"Buffer empty, " + Thread.CurrentThread.Name + " waits.....");
Monitor.Wait(this);
}
// if there is data to read, set bufferFull to false before reading
bufferFull =
false;
DisplayState(
"*" + Thread.CurrentThread.Name + " reads " + buffer + "*");
// tell waiting Producer thread (if there is one) to become ready to execute
Monitor.Pulse(this);
// release lock on this object
Monitor.Exit(this);
// finally actually read the buffer data
return buffer;
}
// end GetMsg
// display current operation and buffer state
public void DisplayState( string operation )
{
Console.WriteLine( "{0,-35}{1,-9}{2}\n", operation, msg, msgFull );
}
}
// end class SharedString
// class Producer's Produce method controls a thread that
// stores values from 1 to 4 in sharedLocation and reads A to D from sharedMsg
class Producer
{
private SharedAndSynchronized sharedLocation;
private Random randomSleepTime;
// ??
public Producer( SharedAndSynchronized shared, Random random )
{
sharedLocation = shared;
randomSleepTime = random;
// ?? add an object from the shared msg class
}
// store values 1-4 in object sharedLocation and read A-D from object sharedMsg
public void Produce()
{
string message;
// sleep for random interval upto 3000 milliseconds,
for (string message //THIS IS WHERE I STOPPED!!!!
Thread.Sleep( randomSleepTime.Next(1, 3000);
// set sharedLocation's buffer value,
// and reads sharedMsg's msg string
for ( int count = 1; count <= 4; count++ )
{
Thread.Sleep( randomSleepTime.Next( 1, 3000 ) );
sharedLocation.SetBuffer( count );
// reads from sharedmsg
}
Console.WriteLine( Thread.CurrentThread.Name + " done producing.\n" );
}
// end method Produce
}
// end class Producer
// class Consumer's Consume method controls a thread that
// loops four times, reads a value from sharedLocation, and writes A-D to sharedMsg
class Consumer
{
private SharedAndSynchronized sharedLocation;
private Random randomSleepTime;
// ??
public Consumer( SharedAndSynchronized shared, Random random, SharedString ss )
{
sharedLocation = shared;
randomSleepTime = random;
// ??
}
// read sharedLocation's value four times and write A-D to sharedMsg
public void Consume()
{
int sum = 0;
// A String array with "A", "B", "C" and "D"??
// get current thread
Thread current = Thread.CurrentThread;
// sleep for random interval upto 3000 milliseconds,
// add sharedLocation's buffer value to sum
// and writes A-D to sharedMsg
for ( int count = 1; count <= 4; count++ )
{
Thread.Sleep( randomSleepTime.Next( 1, 3000 ) );
sum += sharedLocation.GetBuffer();
// ??
}
Console.WriteLine( "*" + Thread.CurrentThread.Name +
" read values totaling: " + sum + "* (should be 10).\n" );
}
// end method Consume
}
// end class Consumer
// this class creates producer and consumer threads
class SharedCell
{
// create producer and consumer threads and start them
static void Main( string[] args )
{
// create shared object used by threads
SharedAndSynchronized holdInteger = new SharedAndSynchronized();
// Random object used by each thread
Random random = new Random();
// create SharedString object??
// create Producer and Consumer objects
Producer producer = new Producer( holdInteger, random ); //??
Consumer consumer = new Consumer( holdInteger, random ); //??
// output column heads and initial buffer state
Console.WriteLine( "{0,-35}{1,-9}{2}", "Operation", "Buffer", "Value to Read?" );
Console.WriteLine( "-----------------------------------------------------------" );
holdInteger.DisplayState(
"Initial state" );
// create threads for producer and consumer and set
// delegates for each thread
ThreadStart pts = new ThreadStart( producer.Produce );
Thread producerThread = new Thread( pts );
producerThread.Name =
"Producer";
ThreadStart cts = new ThreadStart( consumer.Consume );
Thread consumerThread = new Thread( cts );
consumerThread.Name =
"Consumer";
// start each thread
producerThread.Start();
consumerThread.Start();
}
// end method Main
}
// end class SharedCell
}