生产者消费者模式是指生产者和消费者通过一个缓冲区(通常是一个队列)的进行通讯。生产者生产完数据之后不用等待消费者处理,直接放到缓冲区,消费者不找生产者要数据,而是直接从缓冲区里取,这样既能够保持生产者和消费者的并发处理,也可以平衡生产者和消费者的处理能力。

这样做有以下优点:

◇ 降低生产者和消费者之间的耦合性

假设生产者和消费者分别是两个类。如果让生产者直接调用消费者的某个方法,那么生产者对于消费者就会产生依赖(也就是耦合)。将来如果消费者的代码发生变化,可能会影响到生产者。而如果两者都依赖于某个缓冲区,两者之间不直接依赖,耦合也就相应降低了。

◇ 生产者和消费者可以并行运行

生产者直接与消费者通信的话,由于函数调用是同步的(或者叫阻塞的),在消费者的方法没有返回之前,生产者只好一直等在那边。万一消费者处理数据很慢,生产者就会白白糟蹋大好时光。

使用了生产者/消费者模式之后,生产者和消费者可以是两个独立的并发主体(常见并发类型有进程和线程两种,后面的帖子会讲两种并发类型下的应用)。生产者把制造出来的数据往缓冲区一丢,就可以再去生产下一个数据。基本上不用依赖消费者的处理速度。

◇ 平衡生产者和消费者的处理能力

缓冲区还有另一个好处。如果制造数据的速度时快时慢,缓冲区的好处就体现出来了。当数据制造快的时候,消费者来不及处理,未处理的数据可以暂时存在缓冲区中。等生产者的制造速度慢下来,消费者再慢慢处理掉。

下面是一个简单的例子,不包含锁机制

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

设计模式—生产者消费者模式相关推荐

  1. java consumed_Java设计模式—生产者消费者模式(阻塞队列实现)

    生产者消费者模式是并发.多线程编程中经典的 真实世界中的生产者消费者模式 生产者和消费者模式在生活当中随处可见,它描述的是协调与协作的关系.比如一个人正在准备食物(生产者),而另一个人正在吃(消费者) ...

  2. java 消费者模式 多线程_[Java并发-24-并发设计模式] 生产者-消费者模式,并发提高效率...

    生产者 - 消费者模式在编程领域的应用非常广泛,前面我们曾经提到,Java 线程池本质上就是用生产者 - 消费者模式实现的,所以每当使用线程池的时候,其实就是在应用生产者 - 消费者模式. 当然,除了 ...

  3. 设计模式——生产者消费者模式

    1 基本概括 2 主要介绍 2.1 概念 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题.生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消 ...

  4. 设计模式-生产者消费者模式

    常见场景: 某个模块负责产生数据,这些数据由另一个模块来负责处理.产生数据的模块,就形象地称为生产者:而处理数据的模块,就称为消费者. 该模式还需要有一个缓冲区处于生产者和消费者之间,作为一个中介.生 ...

  5. Java并发程序设计(十一)设计模式与并发之生产者-消费者模式

    设计模式与并发之生产者-消费者模式 生产者-消费者模式是一个经典的多线程设计模式.它为多线程间的协作提供了良好的解决方案. 在生产者-消费者模式中,通常由两类线程,即若干个生产者线程和若干个消费者线程 ...

  6. java消费者生产者设计模式_java 多线程并发设计模式之四: 生产者消费者模式

    生产者消费者模式是一个经典的多线程设计模式,其核心思想是:有两类线程和一个内存缓冲区或者队列, 一类线程发起任务,并提交到队列中.另一类线程用来处理这些任务,叫做消费者线程. 这两类线程进行通信的桥梁 ...

  7. 并发设计模式之生产者-消费者模式

    点击查看原文: http://www.joyhwong.com/2016/11/19/并发设计模式之生产者-消费者模式/ 生产者-消费者模式是一个经典的多线程设计模式,它为多线程间的协作提供了良好的解 ...

  8. 设计模式之生产者消费者模式

    简介 通过前几篇文章的学习,我想你已经彻底掌握了wait()方法和notify()方法如何使用以及在哪种情况下使用了,本片文章我们将讲解下设计模式中的生产者消费者模式,我将通过手写一份生产者消费者模式 ...

  9. delphi生产者消费者模式代码_并发设计模式:生产者-消费者模式,并发提高效率...

    生产者 - 消费者模式在编程领域的应用非常广泛,前面我们曾经提到,Java 线程池本质上就是用生产者 - 消费者模式实现的,所以每当使用线程池的时候,其实就是在应用生产者 - 消费者模式. 当然,除了 ...

最新文章

  1. CPU调度(CPU Scheduling)
  2. 计算同比 环比_PowerBI学习教程(三)时间累积同比环比计算
  3. Linux新手上路命令
  4. 计算机技能需求新排名:C语言仅排第 8,第 1 名你想不到!
  5. RTP/RTCP流媒體服務器技術研究
  6. 解决Docker安装MySQL不区分大小写问题
  7. 【优化求解】狼群优化算法matlab源码
  8. 2022年全球与中国电动汽车充电设备市场现状及未来发展趋势
  9. 打印机服务器状态未知怎么办,打印机状态信息不可用是怎么回事
  10. 如何添加BigBoss的Cydia源地址
  11. lingo纳什均衡代码_传统的战略式博弈求解纳什均衡方法——虚拟博弈(Fictitious Play)讲解及其代码...
  12. docker搭建企业级habor仓库
  13. 私有网段IP地址的划分
  14. 如何向天翼云服务器上传文件,天翼云盘如何上传文件?
  15. OpenStack核心组件原理与应用之Keystone
  16. JS 特效学习 002:图片渐显
  17. js中substring()、substr() 、slice()的用法
  18. webstorm 扩大内存
  19. 【P2P网络】DHT协议基础1:Kademlia翻译稿
  20. Sentinel 结合 GateWay 限流

热门文章

  1. maven制作脚手架
  2. Thread.IsBackground
  3. 【紫书】UVA673 平衡的括号 Parentheses Balance
  4. 强制转换类型异常ClassCastException
  5. ClassCastException发生的原因以及解决方案
  6. 华为手机6.0GPS获取不到定位信息
  7. display:box浏览器兼容性
  8. 软件测试 | 边界值测试用例设计方法
  9. mysql读写分离(一)----------mysql安装
  10. 客户端性能测试——WeTest工具的使用