C#实现生产者消费者实验
时间: 2023-10-19 08:13:06 浏览: 138
生产者消费者问题是一个经典的多线程问题,其中有一个生产者线程和多个消费者线程共同操作一个共享的队列,生产者线程向队列中添加元素,消费者线程从队列中取出元素进行处理。为了避免竞争条件和死锁等问题,需要在程序中采用一些同步机制。下面是一个基于C#语言实现的生产者消费者实验:
```csharp
using System;
using System.Threading;
public class Program
{
private static Queue<int> queue = new Queue<int>(10); //定义一个大小为10的队列
private static object lockObj = new object(); //定义一个锁对象
static void Main(string[] args)
{
Thread producerThread = new Thread(new ThreadStart(Producer));
Thread[] consumerThreads = new Thread[5];
for (int i = 0; i < 5; i++)
{
consumerThreads[i] = new Thread(new ThreadStart(Consumer));
consumerThreads[i].Start();
}
producerThread.Start();
}
static void Producer()
{
while (true)
{
lock (lockObj)
{
if (queue.Count < 10)
{
int num = new Random().Next(100);
queue.Enqueue(num); //向队列中添加元素
Console.WriteLine("生产者线程:{0} 生产了一个元素 {1},队列中元素个数为{2}", Thread.CurrentThread.ManagedThreadId, num, queue.Count);
}
else
{
Monitor.Wait(lockObj); //如果队列已满,生产者线程进入等待状态
}
}
Thread.Sleep(1000);
Monitor.PulseAll(lockObj); //通知所有等待的线程有新的元素加入队列
}
}
static void Consumer()
{
while (true)
{
lock (lockObj)
{
if (queue.Count > 0)
{
int num = queue.Dequeue(); //从队列中取出元素
Console.WriteLine("消费者线程:{0} 消费了一个元素 {1},队列中元素个数为{2}", Thread.CurrentThread.ManagedThreadId, num, queue.Count);
}
else
{
Monitor.Wait(lockObj); //如果队列为空,消费者线程进入等待状态
}
}
Thread.Sleep(1000);
Monitor.PulseAll(lockObj); //通知所有等待的线程有新的空位可供添加元素
}
}
}
```
在这个实现中,我们使用了一个 `Queue<int>` 类型的队列来保存元素,使用了一个 `lockObj` 对象作为锁对象。生产者线程通过 `Monitor.Wait()` 进入等待状态,直到队列不为空;消费者线程通过 `Monitor.Wait()` 进入等待状态,直到队列不为满。在向队列中添加或者移除元素时,通过 `lock` 语句块保证对队列的访问是原子操作。在添加或移除元素后,我们通过 `Monitor.PulseAll()` 方法通知所有正在等待的线程有新的元素或空位可供操作。
阅读全文