`
fishyu0817
  • 浏览: 110150 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java设计模式之生产者消费者模式

阅读更多

转载

 

对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的。就像学习每一门编程语言一 样,Hello World!都是最经典的例子。

  实际上,准确说应该是“生产者-消费者-仓储”模型,离开了仓储,生产者消费者模型就显得没有说服力了。

  对于此模型,应该明确一下几点:

  1、生产者仅仅在仓储未满时候生产,仓满则停止生产。

  2、消费者仅仅在仓储有产品时候才能消费,仓空则等待。

  3、当消费者发现仓储没产品可消费时候会通知生产者生产。

  4、生产者在生产出可消费产品时候,应该通知等待的消费者去消费。

  此模型将要结合java.lang.Object的wait与notify、notifyAll方法来实现以上的需求。这是非常重要的。


   /**
   * Java线程:并发协作-生产者消费者模型
  *
   * @author leizhimin 2009-11-4 14:54:36
  */
   public class Test {
  public static void main(String[] args) {
   Godown godown = new Godown(30);
   Consumer c1 = new Consumer(50, godown);
   Consumer c2 = new Consumer(20, godown);
   Consumer c3 = new Consumer(30, godown);
   Producer p1 = new Producer(10, godown);
   Producer p2 = new Producer(10, godown);
   Producer p3 = new Producer(10, godown);
   Producer p4 = new Producer(10, godown);
   Producer p5 = new Producer(10, godown);
   Producer p6 = new Producer(10, godown);
   Producer p7 = new Producer(80, godown);
  c1.start();
   c2.start();
  c3.start();
  p1.start();
  p2.start();
   p3.start();
  p4.start();
  p5.start();
  p6.start();
   p7.start();
  }
  }
  /**
  * 仓库
  */
   class Godown {
  public static final int max_size = 100; //最大库存量
   public int curnum; //当前库存量
  Godown() {
  }
   Godown(int curnum) {
  this.curnum = curnum;
  }
  /**
   * 生产指定数量的产品
  *
  * @param neednum
  */
   public synchronized void produce(int neednum) {
  //测试是否需要生产
   while (neednum + curnum > max_size) {
  System.out.println("要生产的产 品数量" + neednum + "超过剩余库存量" + (max_size - curnum) + ",暂时不能执行生产任务!");
   try {
  //当前的生产线程等待
  wait();
   } catch (InterruptedException e) {
  e.printStackTrace();
  }
   }
  //满足生产条件,则进行生产,这里简单的更改当前库存量
  curnum += neednum;
   System.out.println("已经生产了" + neednum + "个产品,现仓储量为" + curnum);
  //唤醒 在此对象监视器上等待的所有线程
  notifyAll();
  }
  /**
  * 消费指定数量的产品
   *
  * @param neednum
  */
   public synchronized void consume(int neednum) {
  //测试是否可消费
   while (curnum < neednum) {
  try {
  //当前的生产线程等待
   wait();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  }
  //满足消费条件,则进行消费,这里简单的更改当前库存量
   curnum -= neednum;
  System.out.println("已经消费了" + neednum + "个产品,现仓 储量为" + curnum);
  //唤醒在此对象监视器上等待的所有线程
  notifyAll();
  }
   }
  /**
  * 生产者
  */
  class Producer extends Thread {
   private int neednum; //生产产品的数量
  private Godown godown; //仓库
   Producer(int neednum, Godown godown) {
  this.neednum = neednum;
   this.godown = godown;
  }
  public void run() {
  //生产指定数量的 产品
  godown.produce(neednum);
  }
  }
  /**
  * 消费者
   */
  class Consumer extends Thread {
  private int neednum; //生 产产品的数量
  private Godown godown; //仓库
   Consumer(int neednum, Godown godown) {
  this.neednum = neednum;
   this.godown = godown;
  }
  public void run() {
  //消费指定数量的 产品
  godown.consume(neednum);
  }
  }

 


   已经生产了10个产品,现仓储量为40
  已经生产了10个产品,现仓储量为50
  已经消费了50个产品,现仓储量为0
   已经生产了80个产品,现仓储量为80
  已经消费了30个产品,现仓储量为50
  已经生产了10个产品,现仓储量为60
   已经消费了20个产品,现仓储量为40
  已经生产了10个产品,现仓储量为50
  已经生产了10个产品,现仓储量为60
   已经生产了10个产品,现仓储量为70
  Process finished with exit code 0

  说明:

  对于本例,要说明的是当发现不能满足生产或者消费条件的时候,调用对象的wait方法,wait方法的作用是释放当前线程的所获得的锁,并调用 对象的notifyAll() 方法,通知(唤醒)该对象上其他等待线程,使得其继续执行。这样,整个生产者、消费者线程得以正确的协作执行。

  notifyAll() 方法,起到的是一个通知作用,不释放锁,也不获取锁。只是告诉该对象上等待的线程“可以竞争执行了,都醒来去执行吧”。

  本例仅仅是生产者消费者模型中最简单的一种表示,本例中,如果消费者消费的仓储量达不到满足,而又没有生产者,则程序会一直处于等待状态,这当 然是不对的。实际上可以将此例进行修改,修改为,根据消费驱动生产,同时生产兼顾仓库,如果仓不满就生产,并对每次最大消费量做个限制,这样就不存在此问 题了,当然这样的例子更复杂,更难以说明这样一个简单模型。

分享到:
评论
1 楼 帅先勃 2012-07-28  

相关推荐

    Java 生产者消费者模式

    自己空闲时间写的一个生产者和消费者模式。中间使用了中介者设计模式。大家可以参考下。

    【资源免费下载】Java代码积累丨大话设计模式(Java实现版本)、线程协作

    生产者-消费者 设计模式参考《大话设计模式》 工厂简单模式 创造型模式 工厂方法模式 抽象工厂模式 原型模式 建造者模式 单例模式 结构型模式 队列模式 桥接模式 组合模式 装饰模式 外观模式 享元模式 代理模式 行为...

    用Java实现23种设计模式

    用Java实现23种设计模式 1. 创建型模式 工厂模式(Factory Pattern) 抽象工厂模式(Abstract Factory Pattern) 单例模式(Singleton Pattern) ... 生产者消费者模式(Producer Consumer Pattern)

    JAVA课程设计(生产者-消费者问题)

    编写该文档的目的在于从总体设计的角度明确生产者-消费者的功能和处理模式,明确生产者-消费者的接口,使系统开发人员和产品管理人员明确产品功能,可以有针对性的进行系统开发、测试、验收等各方面的工作

    java设计模式大全

    最全面的设计模式,消费者生产者,java比备

    JAVA与设计模式PPT版本(通俗易懂)

    设计模式之Factory -工厂模式 客户类和工厂类分开。消费者任何时候需要某种产品,只需向工厂请求即可。消费者无须修改就可以接纳新产品。 缺点是当产品修改时,工厂类也要做相应的修改。 追MM少不了请吃饭了,麦当劳...

    Java多线程并发生产者消费者设计模式实例解析

    主要介绍了Java多线程并发生产者消费者设计模式实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    java多线程设计模式详解(PDF及源码).zip

    java多线程设计模式详解,包括了单线程,生产者和消费者,各种线程方法的解释!

    Java常用并发设计模式精讲

    Java常用并发设计模式精讲 内容简介: 1、优雅终止线程的设计模式 2、避免共享的设计模式 3、多线程版本的if模式 4、多线程分工模式 5、生产者 - 消费者模式的优点 6、过饱问题解决方案

    精讲23种设计模式

    通过简单易懂的话语总结与讲解了23种设计模式。

    关于Java23种设计模式的有趣见解.

    FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和...消费者任何时候需要某种产品,只需向工厂请求即可。消费者无须修改就可以接纳新产品。缺点是当产品修改时,工厂类也要做相应的修改。如:如何创建及如何向客户端提供。

    JAVA设计模式

    里面有JAVA 设计模式 工厂模式 单例模式 观察者模式 装饰者模式以及future 和生产消费模式的实例 详细讲解请查看我的博客:http://my.csdn.net/ajun495175289

    基于Java实现生产者与消费者算法模拟【100010232】

    本次课程设计选到的题目为生产者消费者算法模拟,通过需求分析和资料搜寻,掌握到生产者/消费者的模式原理和优点,同时也了解到了几种可以实现生产者消费者的方式,如信号量方式,管程方式,阻塞队列方式等。

    java 的23种设计模式

    23种设计模式(详解) 1、factory(工厂)?追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德 基,只管向服务员说“来四个鸡翅”就行了。麦当劳和...

    JAVA 23种模式

    从追MM谈Java的23种设计模式 1、FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“来四个鸡翅”就行了。麦当劳和...

    从追MM谈Java的23种设计模式.txt

    从追MM谈Java的23种设计模式  1、FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯 德基,只管向服务员说“来四个鸡翅”就行了。麦当劳和...

    追MM与JAVA的23种设计模式

    消费者任何时候需要某种产品,只需向工厂请求即可。消费者无须修改就可以接纳新产品。缺点是当产品修改时,工厂类也要做相应的修改。如:如何创建及如何向客户端提供。 2、BUILDER—MM最爱听的就是“我爱你”这句...

    JAVA高并发高性能高可用高扩展架构视频教程

    高并发之单(多)生产者消费者线程 高并发复用数据库链接技术详解之数据库连接池 类加载器的高级特性(自定义类加器实现加密解密) iBATIS开源主流框架(实现半自动化hibernate) 企业实用技能之详解(眼睛横纹模式验证码...

    Advanced-Programming-Topics-Java:该存储库包括Java编程的高级主题和框架。 这包括JDBC框架,套接字编程,REST API,Java消息服务,Zoo-Keeper,设计模式,Hibernate框架,Spring框架,密码学和消费者生产者框架。

    这包括JDBC框架,套接字编程,REST API,Java消息服务,Zoo-Keeper,设计模式,Hibernate框架,Spring框架,密码学和消费者生产者框架。 安装以下软件和应用程序以更新您的工作站并运行存储库中所有提供的解决方案...

Global site tag (gtag.js) - Google Analytics