设计模式—生产者消费者模式
来源:互联网 发布:python基础教程 微盘 编辑:程序博客网 时间:2024/05/02 00:02
生产者消费者模式是指生产者和消费者通过一个缓冲区(通常是一个队列)的进行通讯。生产者生产完数据之后不用等待消费者处理,直接放到缓冲区,消费者不找生产者要数据,而是直接从缓冲区里取,这样既能够保持生产者和消费者的并发处理,也可以平衡生产者和消费者的处理能力。
这样做有以下优点:
◇ 降低生产者和消费者之间的耦合性
假设生产者和消费者分别是两个类。如果让生产者直接调用消费者的某个方法,那么生产者对于消费者就会产生依赖(也就是耦合)。将来如果消费者的代码发生变化,可能会影响到生产者。而如果两者都依赖于某个缓冲区,两者之间不直接依赖,耦合也就相应降低了。
◇ 生产者和消费者可以并行运行
生产者直接与消费者通信的话,由于函数调用是同步的(或者叫阻塞的),在消费者的方法没有返回之前,生产者只好一直等在那边。万一消费者处理数据很慢,生产者就会白白糟蹋大好时光。
使用了生产者/消费者模式之后,生产者和消费者可以是两个独立的并发主体(常见并发类型有进程和线程两种,后面的帖子会讲两种并发类型下的应用)。生产者把制造出来的数据往缓冲区一丢,就可以再去生产下一个数据。基本上不用依赖消费者的处理速度。
◇ 平衡生产者和消费者的处理能力
缓冲区还有另一个好处。如果制造数据的速度时快时慢,缓冲区的好处就体现出来了。当数据制造快的时候,消费者来不及处理,未处理的数据可以暂时存在缓冲区中。等生产者的制造速度慢下来,消费者再慢慢处理掉。
下面是一个简单的例子,不包含锁机制
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;namespace DesignPatern{ //队列临时类 public class QueueInfo { public string ID { get; set; } public override string ToString() { return this.ID; } } public class BusinessInfoHelper { #region 解决发布时含有优质媒体时,前台页面卡住的现象 //原理:利用生产者消费者模式进行入列出列操作 public readonly static BusinessInfoHelper Instance = new BusinessInfoHelper(); private int N = 100; private BusinessInfoHelper() { } private Queue<QueueInfo> ListQueue = new Queue<QueueInfo>(); public void StartProducer() { Thread thread = new Thread(threadStartProduct); thread.Start(); } private void threadStartProduct() { int k = 0; while(true) { if(ListQueue.Count<N) { try { k++; AddQueue(k.ToString()); } catch(Exception ex) { throw new Exception(ex.ToString()); } } } } public void AddQueue(string pid) //入列 { QueueInfo queueinfo = new QueueInfo(); queueinfo.ID = pid; ListQueue.Enqueue(queueinfo); } public void StartConsumer()//启动 { Thread thread = new Thread(threadStartConsume); thread.IsBackground = true; thread.Start(); } private void threadStartConsume() { while (true) { if (ListQueue.Count > 0) { try { ScanQueue(); } catch (Exception ex) { throw new Exception(ex.Message); } } else { //没有任务,休息3秒钟 Thread.Sleep(3000); } } } //要执行的方法 private void ScanQueue() { while (ListQueue.Count > 0) { try { //从队列中取出 QueueInfo queueinfo = ListQueue.Dequeue(); Console.WriteLine(queueinfo.ToString()); //取出的queueinfo就可以用了,里面有你要的东西 //以下就是处理程序了 //。。。。。。 } catch (Exception ex) { throw new Exception(ex.ToString()); } } } #endregion }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;namespace DesignPatern{ class Program { private static object lockObject = new Object(); static void Main(string[] args) { DesignPatern.BusinessInfoHelper.Instance.StartProducer(); DesignPatern.BusinessInfoHelper.Instance.StartConsumer(); //Thread.Sleep(300000); } }}
写的不完整等待后续完善。。。
参考资料:
http://blog.csdn.net/kaiwii/article/details/6758942
http://www.infoq.com/cn/articles/producers-and-consumers-mode/#0-tsina-1-97643-397232819ff9a47a7b7e80a40613cfe1
- 设计模式—生产者消费者模式
- 设计模式-生产者消费者模式
- 设计模式 - 生产者-消费者模式
- 设计模式--生产者消费者模式
- 设计模式-生产者消费者模式
- 生产者—消费者模式
- 架构设计:生产者/消费者模式
- 架构设计:生产者/消费者模式
- 架构设计:生产者/消费者模式
- 架构设计:生产者/消费者模式
- 架构设计:生产者/消费者模式
- 架构设计:生产者/消费者模式
- 架构设计:生产者/消费者模式
- 架构设计:生产者/消费者模式
- 架构设计:生产者/消费者模式
- 架构设计:生产者/消费者模式
- 架构设计:生产者/消费者模式
- 架构设计:生产者/消费者模式
- Android 四大组件学习之Service六
- 库函数(无线视频)(7.22)
- 基于Ubuntu14.04的RK3288_PopMetal Android开发环境搭建过程小记
- Codeforces Round #312 (Div. 2) B. Amr and The Large Array
- 初创公司需不需要产品经理?
- 设计模式—生产者消费者模式
- fragment + viewpager 实现tabhost功能
- 内存实验相关分析(7.23)
- Android 服务器之FTP服务器上传下载功能的实现
- Android 中Service 和Activity之间传值。(涉及BroadCast的基本用法)
- 欢迎使用CSDN-markdown编辑器
- JavaSE初学笔记之<多线程>
- 如何查看自己电脑上windows installer的版本?
- android 用xml实现点击效果