gpt4 book ai didi

c# - 在C#中管理线程关系

转载 作者:行者123 更新时间:2023-12-03 12:49:54 26 4
gpt4 key购买 nike

现在,我正在学习C#中的多线程及其用法。所以,我面临如下问题:
(很抱歉我这么简单的问题)

假设我们有两个名为Producer和Consumer的类。生产者任务在程序运行时产生4个数字,而消费者任务正在消耗和使用这些数字,并在程序结束时返回它们的总和。

消费者类别定义:

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;
}
}
}

生产者类别的定义如下:
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;
}
}
}

而且,我们的 HoldInteger类包含Buffer变量,生产者可以编写此变量,而消费者可以从中读取。我结合了这些类,并在我的主要方法中编写了以下代码:
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();
}

所以,我的问题是 How can i manage this relationship With Low Memory and Time Wasting ?
请注意,这些线程管理代码将放置在 HoldInteger类主体中。

感谢您的关注。

最佳答案

我将HoldInteger类替换为BlockingQueue you can find an implementation here,并进一步了解实现背后的原因check this question。我认为.NET 4.0可能也有阻塞队列。随后,这种方法将使事情变得更容易管理:

class Producer
{
//...

public void Produce()
{
for (int i = 1; i <= 4; i++)
{
Thread.Sleep(randomSleepTime.Next(1, 3000));
blockingIntQueue.Enqueue(i);
}
}
}

您的消费者现在将如下所示:
class Consumer
{
//...

public void Consume()
{
int value = 0;
for (int i = 1; i <= 4; i++)
{
if( blockingIntQueue.TryDequeue(out value) )
{
sum += value;
}
}
}
}

但是,如果要保留 HoldInteger(如果有某种要求),则可以将阻塞队列放入 HoldIntegerUnsynchronized类中,而不要使用缓冲区(应该很简单),您将获得相同的结果。

注意:通过这种方法,不再需要担心丢失值或读取过时的值,因为线程没有在正确的时间唤醒。这是使用“缓冲区”的潜在问题:

即使您的整数持有人确实安全地处理了底层的“缓冲区”,也仍然不能保证您将获得所需的所有整数。考虑到这一点:

案例1
Producer wakes up and writes integer.
Consumer wakes up and reads integer.

Consumer wakes up and reads integer.
Producer wakes up and writes integer.

案例2
Consumer wakes reads integer.
Producer wakes up and writes integer.

Producer wakes up and writes integer.
Consumer wakes up and reads integer.

由于计时器不够精确,这种事情是完全可能的,在第一种情况下,它将导致消费者读取陈旧的值,而在第二种情况下,它将导致消费者错过一个值。

关于c# - 在C#中管理线程关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7167630/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com