Now, i am learning multi-threading and usage of it in C#. So, i face the problem as below:
(Sorry for my so simple question)
Suppose that, we have two classes named Producer and Consumer. Producer task is producing 4 numbers while program running and Consumer task is consuming and using those numbers and return the sum of them at the end of program.
Consumer Class definition:
class Consumer
{
private HoldInteger sharedLocation;
private Random randomSleepTime;
public Consumer(HoldInteger shared, Random random)
{
sharedLocation = shared;
randomSleepTime = random;
}
public void Consume()
{
int sum = 0;
for (int i = 1; i <= 4; i++)
{
Thread.Sleep(randomSleepTime.Next(1, 3000));
sum += sharedLocation.Buffer;
}
}
}
and the definition of Producer Class is as below :
class Producer
{
private HoldInteger sharedLocation;
private Random randomSleepTime;
public Producer(HoldInteger shared, Random random)
{
sharedLocation = shared;
randomSleepTime = random;
}
public void Produce()
{
for (int i = 1; i <= 4; i++)
{
Thread.Sleep(randomSleepTime.Next(1, 3000));
sharedLocation.Buffer = i;
}
}
}
And also, we have HoldInteger class contains Buffer variable that producer write this variable and consumer read from that. I combine these classes and program the below code in my main method:
static void Main(string[] args)
{
HoldInteger holdInteger = new HoldInteger();
Random random = new Random();
Producer producer = new Producer(holdInteger, random);
Consumer consumer = new Consumer(holdInteger, 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();
}
So, my question is that How can i manage this relationship With Low Memory and Time Wasting ?
Please note that, these threads management code will be placed in HoldInteger class body.
Thanks for your attention.
I would replace the
HoldIntegerclass with aBlockingQueue, you can find an implementation here and for more details on the reason behind the implementation, check this question. I think .NET 4.0 might have a blocking queue too. This approach will subsequently make things a lot easier to manage:Your consumer will look like this now:
However, if you want to keep the
HoldInteger(if this is some sort of requirement), then you can place the blocking queue inside theHoldIntegerUnsynchronizedclass instead of having a buffer (should be trivial to do) and you will achieve the same result.Note: with this approach you no longer have to worry about missing a value or reading a stale value because the threads don’t wake up at exactly the right time. Here is the potential problem with using a “buffer”:
Even if your integer holder does handle the underlying “buffer” safely, you are still not guaranteed that you will get all the integers that you want. Take this into consideration:
Case 1
Case 2
Since the timer is not precise enough, this sort of thing is entirely possible and in the first case it will cause the consumer to read a stale value, while in the second case it will cause the consumer to miss a value.