在《java 同步和互斥程序说明》这篇文章的基础上,来实现下面的程序

桌上有一个空盘子,只允许放一个水果。爸爸可以向盘中放苹果,也可以向盘中放桔子,儿子专等吃盘中的桔子,女儿专等吃盘中的苹果。规定当盘空时,一次只能放一只水果。

下面是程序的具体实现代码,在写这个程序的时候,有点小问题,纠结了很长时间,于是在csdn论坛上发表帖子终于得到了解决

先说说涉及到的类的作用,首先Fruits作为一个水果的父类,Apple和Orange是Fruits类的扩展类。CriticalResources类是临界资源类,作为缓冲区用,里面封装了数组大小为一的Fruits数组,可以看成“盘子”;ProducerOrange为生产橘子的类 ProducerApple为生产桔子的类 ConsumerApple(消费苹果的类) ConsumerOrange(消费桔子的类)

水果类代码如下

public class Fruits {private String name;public Fruits(String name) {this.name = name;}@Overridepublic String toString() {return name;}public Fruits() {super();}}

苹果类代码
public class Apple extends Fruits {public Apple(String name) {super(name);}public Apple() {// TODO Auto-generated constructor stub}}

橘子类代码
public class Orange extends Fruits { public Orange(String name) { super(name); } public Orange() {// TODO Auto-generated constructor stub}
}

下面是作为缓冲区盘子的代码:

public class CriticalResources {private int index = 0;private static Fruits[] fruites = new Fruits[1];// 默认临界区有五个商品private ProducerApple pa = new ProducerApple(this);private ProducerOrange po = new ProducerOrange(this);private ConsumerApple ca = new ConsumerApple(this);private ConsumerOrange co = new ConsumerOrange(this);/*** 向临界资源里添加商品 利用synchronized关键字实现同步 添加后数组指针+1* 如果临界资源数组里面装满了商品不能再生产,则生产线程等待以便让消费者消费* * @param goods*/public synchronized void push(Fruits goods) {//while (this.index == this.fruites.length) {try {this.wait();} catch (InterruptedException e) {//相应中断,继续执行while(循环),可能就要跳出去}}this.notifyAll();// 唤醒生产者this.fruites[index++] = goods;}/*** 从临界资源里拿商品,先减一后返回 如果index==0说明, 临界资源数组里面没有商品,不能在消费 消费线程阻塞, 让生产者生产 则让生产者* * @return*/public synchronized Fruits pop() {while (this.index == 0) {try {this.wait();} catch (InterruptedException e) {//相应中断,继续执行while(循环),可能就要跳出去}}this.notifyAll();// 唤醒消费者return fruites[--index];}/*** 看看是不是空了* * @return*/public synchronized Fruits peek() {if (this.index == 0)return null;elsereturn fruites[index - 1];}public int getIndex() {return index;}public void setIndex(int index) {this.index = index;}public Fruits[] getFruites() {return fruites;}}

下面是生产桔子和消费桔子的代码

public class ProducerOrange implements Runnable {CriticalResources cr = null;public ProducerOrange(CriticalResources cr) {super();this.cr = cr;}int count = 5; //做5次@Overridepublic void run() {while(count-->0)synchronized (cr) {while (cr.peek() != null) {try {cr.wait();// 该生产这等待} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}Fruits fruits = new Orange("橘子");cr.push(fruits);System.out.println("橘子生产商生产了" + fruits);cr.notifyAll();}}}
/*** 消费橘子的消费者* * @author Administrator* */
public class ConsumerOrange implements Runnable {private CriticalResources cr = null;// 封装一个临界资源对象,以便消费public ConsumerOrange(CriticalResources cr) {super();this.cr = cr;}int count = 5;@Overridepublic void run() {while (count-- > 0)// 如果缓冲区是苹果synchronized (cr) {while (!(cr.peek() instanceof Orange)) {try {cr.wait();// 该消费者等待} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}Fruits fruits = cr.pop();System.out.println("----橘子消费者消费了-------" + fruits);cr.notifyAll();}}}

下面是生产苹果核消费苹果的代码

package arthur.thread.producerandcoustomer;
public class ProducerApple implements Runnable {private CriticalResources cr = null;// 封装一个临界资源对象,以便生产 public ProducerApple(CriticalResources cr) {super();this.cr = cr;}private int count = 5;@Overridepublic void run() {while (count-- > 0)synchronized (cr) {while ((cr.peek() != null)) {try {cr.wait();// 缓冲区满,该生产者等待 } catch(InterruptedException e){//响应中断}} /如果不加锁,此处容易被打断Fruits fruits = new Apple("苹果");cr.push(fruits);System.out.println("苹果生产商生产了" + fruits);cr.notifyAll();}}}
}
/** * 消费苹果的消费者 * * @author Arthur * */ public class ConsumerApple implements Runnable {private CriticalResources cr = null;// 封装一个临界资源对象,以便消费 public ConsumerApple(CriticalResources cr) {super();this.cr = cr;}int count = 5;@Overridepublic void run() {while (count-- > 0) synchronized (cr) {while (!(cr.peek() instanceof Apple)) {try {cr.wait();} catch (InterruptedException e) {//相应中断}}Fruits fruits = cr.pop();System.out.println("----苹果消费者消费了-------" + fruits);cr.notifyAll();}}
} 

客户端代码

public class Client {/*** @param args*/public static void main(String[] args) {CriticalResources cr = new CriticalResources();// 生产苹果实例ProducerApple appleP = new ProducerApple(cr);// 消费苹果实例ConsumerApple appleC = new ConsumerApple(cr);// 橘子生产者实例ProducerOrange orangeP = new ProducerOrange(cr);// 橘子消费者实例ConsumerOrange orangeC = new ConsumerOrange(cr);// 生产苹果线程Thread pThread = new Thread(appleP);// 消费苹果线程Thread cThread = new Thread(appleC);// 生产橘子线程Thread pt = new Thread(orangeP);// 消费橘子线程Thread ct = new Thread(orangeC);pThread.start();cThread.start();pt.start();ct.start();}}

运行结果

苹果生产商生产了苹果
----苹果消费者消费了-------苹果
橘子生产商生产了橘子
----橘子消费者消费了-------橘子
苹果生产商生产了苹果
----苹果消费者消费了-------苹果
橘子生产商生产了橘子
----橘子消费者消费了-------橘子
苹果生产商生产了苹果
----苹果消费者消费了-------苹果
橘子生产商生产了橘子
----橘子消费者消费了-------橘子
苹果生产商生产了苹果
----苹果消费者消费了-------苹果
橘子生产商生产了橘子
----橘子消费者消费了-------橘子
苹果生产商生产了苹果
----苹果消费者消费了-------苹果
橘子生产商生产了橘子
----橘子消费者消费了-------橘子








												

生产者消费者之爸爸妈妈儿子女儿苹果橘子编程实现相关推荐

  1. 爸爸妈妈儿子女儿吃水果问题以及五个哲学家吃饭问题

    在PV操作中会有一个经典的例子就是爸爸妈妈儿子女儿吃水果问题,爸爸妈妈向盘子里放入水果,儿子女儿向盘子取水果.然而爸爸只向盘子放苹果,妈妈只向盘子放橘子,女儿只能吃苹果,儿子只能吃橘子.并且盘子里只能 ...

  2. 生产者消费者模型(条件变量)

    三种关系:互斥,同步,互斥和同步 两类角色:生产者,消费者(线程) 一个交易场所:生产者消费者共享的区域 卖苹果的模型 dish上面只有一个苹果 买家必须要等卖家把苹果放到dish上才可以去买苹果. ...

  3. 管程法解决生产者消费者问题

    生产者-消费者模式是一个十分经典的多线程并发协作的模式,弄懂生产者-消费者问题能够让我们对并发编程的理解加深.所谓生产者-消费者问题,实际上主要是包含了两类线程,一种是生产者线程用于生产数据,另一种是 ...

  4. Java实现生产者消费者案例

    目录 一.生产者消费者模式概述 二.生产者消费者案例 三.代码 奶箱类(Box): 生产者类(Producer): 消费者类(Customer): 测试类(BoxDemo): 四.运行结果 一.生产者 ...

  5. 实现生产者消费者的三种方式

    文章目录 wait/notify的消息通知机制 预备知识 wait/notify消息通知潜在的一些问题 notify过早通知 等待wait的条件发生变化 假死状态 wait/notifyAll实现生产 ...

  6. 多线程-并发编程(7)-生产者消费者模式及非阻塞队列与阻塞队列实现

    生产者消费者模式是一个十分经典的多线程协作模式 弄懂生产者消费者问题能够让我们对多线程编程的理解更加深刻 存在3个元素 1.生产者(类比厨师) 2.生产者的生产产品(类比美食) 3.消费者(类比吃货) ...

  7. Java基础学习之生产者消费者(29)

    1.1 生产者消费者模式概述 生产者消费者模式是一个十分经典的多线程协作模式,弄懂生产者消费者问题能够让我们对多线程编程理解更加深刻. 包含两类线程: 一类是生产者线程用于生产数据 一类是消费者线程用 ...

  8. Python多线程实现生产者消费者模式

    什么是生产者消费者模式 在软件开发的过程中,经常碰到这样的场景: 某些模块负责生产数据,这些数据由其他模块来负责处理(此处的模块可能是:函数.线程.进程等).产生数据的模块称为生产者,而处理数据的模块 ...

  9. python queue 生产者 消费者_Queue: 应用于生产者-消费者模式的Python队列

    图片来源于网络 版权声明 © 著作权归作者所有 允许自由转载,但请保持署名和原文链接. 不允许商业用途.盈利行为及衍生盈利行为. 什么是Queue? Queue是Python标准库中的线程安全的队列( ...

  10. Java多线程(实现多线程、线程同步、生产者消费者)

    1.实现多线程 1.1简单了解多线程[理解] 是指从软件或者硬件上实现多个线程并发执行的技术. 具有多线程能力的计算机因有硬件支持而能够在同一时间执行多个线程,提升性能. 1.2并发和并行[理解] 并 ...

最新文章

  1. html标记汇总,HTML标记语法汇总.doc
  2. Python Flask-表单提交方式
  3. C#如何开发多语言支持的Winform程序
  4. 04 组件与Props
  5. android网络监听
  6. Mybatis中的动态SQL记录
  7. 持续更新-Linux应用一句话
  8. python是一种什么类型的高级语言_python介绍 编程语言分类及对比 python解释器安装(多版本共存) 变量 数据类型(三种)...
  9. 启动Flume Agent出现“A fatal error occurred while running“解决方法
  10. linux下查看文件描述符,linux下文件描述符的查看及分析
  11. 《网络基础》p84.interface gigabitethernet 0/0/0报错
  12. WinCC7.0如何通过授权管理器用U盘进行导入和导出授权?
  13. seo三部曲之关键词策略
  14. sql server 存储过程中 SET NOCOUNT ON是什么意思?
  15. Java 8中Collectors.toMap空指针异常源码分析
  16. matlab怎么提取小数部分,[转载]如何在Matlab中得到一个单、双精度数的整数部分和小数部分?...
  17. 计算机科学与技术考研双非院校排名,ESI工科小校较好新排名,两所双非院校冲进世界500强!...
  18. 很多人都在说Java已经饱和了,未来的就业前景究竟怎么样?
  19. SAP的后台配置SPRO中获利分析COPA相关的问题(实为经营范围相关表)
  20. Shopex4.85 cms后台管理员权限获取webshell

热门文章

  1. linux断点续传程序,Linux下怎么实现断点续传
  2. 18. Django进阶:中间件
  3. Javascript特效:侧边广告
  4. 矩阵运算_SLAM中用到的矩阵计算_基本公式及知识汇总
  5. 深度学习笔记_损失函数softmax和SVM
  6. bootstrap table 标题列重复
  7. Java语言基础:常量和变量
  8. QT 5 初学1 多窗口切分-续
  9. LeetCode(8):字符串转整数(atoi)
  10. ●BZOJ 2393 Cirno的完美算数教室