C# 生产者消费者模式 自己写的一个Demo
2016-01-06 17:17 Lasthelloworld 阅读(793) 评论(0) 收藏 举报模拟环境:
Worker--生产工人
Customer--消费者
WorkQueue--缓存队列
模拟两个工人不停生产产品,生产5个产品装为一箱,放入缓存队列,若队列中有10箱时(满),让工人等待1秒再继续检查队列是否满,不为满时继续生产。
模拟消费者不停从缓存队列中取东西,若队列为空时,等待工人生产,等待时间4秒。
以下是代码:
Worker--生产工人
using System; using System.Collections.Generic; using System.Linq; using System.Text; using CommonHelper.Common; using System.Threading; namespace DesignModel.WorkerAndCustomerDemo { /// <summary> /// 产品类名 /// </summary> public enum ProductType { Phone, Computer, Pad } /// <summary> /// 生产者 /// </summary> public class Worker { #region 属性 //生产者名 private string _Name; public string Name { get { return _Name; } set { _Name = value; } } //生产盒子 private List<ProductModel> _ProductBox; //工作队列 private WorkQueue<List<ProductModel>> _queue; //工作线程 public Thread _thread; //生产者等待时间 private int Speed = 1000; #endregion public Worker(WorkQueue<List<ProductModel>> queue) { this._queue = queue; _ProductBox = new List<ProductModel>(); _thread = new Thread(new ThreadStart(Start)); } //开始工作 private void Start() { while (true) { if (!IsWait()) { ProductModel product = CreateProduct(); InsertBox(product); } else { Thread.Sleep(Speed);//生产者等待时间 Console.WriteLine(string.Format("{0} Wait for Working",_thread.Name)); } } } /// <summary> /// 队列满时,线程进入等待10秒 /// </summary> /// <returns></returns> private bool IsWait() { return _queue.MaxSize == _queue.Count; } //生成一个产品 public ProductModel CreateProduct() { int randomindex = RandomHelper.GetIntRandom(1, 4); ProductType productType = (ProductType)randomindex; ProductModel product = new ProductModel() { Id = System.Guid.NewGuid().ToString(), Name = SelectProductType(productType), CreateBy = this._Name, DateTime = DateTime.Now }; return product; } //装箱发送 public void InsertBox(ProductModel product) { //小于5个产品,都装箱 if (_ProductBox.Count < 5) { _ProductBox.Add(product); Console.WriteLine(string.Format("{0}生产产品正在装箱",this.Name)); } else { Send(); Console.WriteLine(string.Format("{0}装满一箱放入队列", this.Name)); } } //发送给缓冲区队列 public void Send() { List<ProductModel> list =new List<ProductModel>();//地址传递必须重新赋值操作---深拷贝 foreach (ProductModel item in _ProductBox) { list.Add(item); } _queue.EnqueueBox(list); _ProductBox.Clear();//清空盒子 } /// 随机获取产品名 public string SelectProductType(ProductType TypeIndex) { ProductType productType = ProductType.Phone; switch (TypeIndex) { case ProductType.Phone: productType = ProductType.Phone; break; case ProductType.Computer: productType = ProductType.Computer; break; case ProductType.Pad: productType = ProductType.Pad; break; default: productType = ProductType.Phone; break; } return productType.ToString(); } } }
Customer--消费者
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace DesignModel.WorkerAndCustomerDemo { /// <summary> /// 消费者 /// </summary> public class Customer { #region 属性 //消费者名 private string _Name; public string Name { get { return _Name; } set { _Name = value; } } //产品缓存队列 private WorkQueue<List<ProductModel>> _queue; //消费线程 public Thread _thread; //消费者等待时间 private int Spead = 5000;//消费者等待时间 #endregion public Customer(WorkQueue<List<ProductModel>> queue) { this._queue = queue; _thread = new Thread(new ThreadStart(Start)); _thread.Name = "消费者"; } public void Start() { while (true) { if (!IsWait()) { Cusum(); } else { Thread.Sleep(Spead); Console.WriteLine(string.Format("{0} Wait for Cusuming", _thread.Name)); } } } public bool IsWait() { return _queue.IsEmpty; } public void Cusum() { List<ProductModel> box = this._queue.TryDequeueBox(); if (box != null && box.Count>0) { foreach (ProductModel item in box) { //Console.WriteLine(string.Format("消费了一个箱子中的一个产品:{0}", item.Name)); } Console.WriteLine(string.Format("消费了一个箱子中的一个产品:{0}", box[0].Name)); } } } }
WorkQueue--缓存队列
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections.Concurrent; using System.Threading;//线程安全队列.net4.0后 namespace DesignModel.WorkerAndCustomerDemo { /// <summary> /// 缓冲区队列 /// 由生产者和消费者共享 /// </summary> public class WorkQueue<T> :ConcurrentQueue<T> { /// <summary> /// 队列工作形式 /// </summary> public enum WorkType { Add, Get, NotAciton } public int MaxSize = 10;//队列最大值 private static readonly object _Lockobj = new object();//锁对象 /// <summary> /// 尝试移除并返回位于 ConcurrentQueue<T> 开始处的对象 /// </summary> /// <returns></returns> public T TryDequeueBox() { T _obj = default(T); if (!this.IsEmpty)//如果队列不为空,也就是有产品 this.TryDequeue(out _obj); return _obj; } /// <summary> /// 将箱子添加到队列末尾处 /// </summary> /// <returns></returns> public void EnqueueBox(T box) { if (this.MaxSize > this.Count) { this.Enqueue(box); } } } }
调用方法:
WorkQueue<List<ProductModel>> quere = new WorkQueue<List<ProductModel>>(); //创建工人和消费者 Customer customer = new Customer(quere); Worker w1 = new Worker(quere); Worker w2 = new Worker(quere); //设置属性 w1.Name = "工人1"; w1._thread.Name = "工人1线程"; w2.Name = "工人2"; w2._thread.Name = "工人2线程"; //启动 w1._thread.Start(); w2._thread.Start(); customer._thread.Start(); Console.Read();
以上是本人完成的代码:
下面有几个疑问,问下吧友:
1.如何使用C#事件委托,消息通知的方式完成上面的代码,例如,队列满时,事件通知生产者等待。
2.线程并发时,如何线程之间通讯,例如工人1给工人2之间。
3.目前装箱的过程中,会出现两个工人装一个箱子的情况,请问有没有办法让每个工人独享当前箱子。
浙公网安备 33010602011771号