1
Answer

Multithreads - two threads manipulating same object

alex

alex

17y
2.3k
1

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

}

Answers (1)