生产者消费者之爸爸妈妈儿子女儿苹果橘子编程实现
桌上有一个空盘子,只允许放一个水果。爸爸可以向盘中放苹果,也可以向盘中放桔子,儿子专等吃盘中的桔子,女儿专等吃盘中的苹果。规定当盘空时,一次只能放一只水果。
下面是程序的具体实现代码,在写这个程序的时候,有点小问题,纠结了很长时间,于是在csdn论坛上发表帖子终于得到了解决
先说说涉及到的类的作用,首先Fruits作为一个水果的父类,Apple和Orange是Fruits类的扩展类。CriticalResources类是临界资源类,作为缓冲区用,里面封装了数组大小为一的Fruits数组,可以看成“盘子”;ProducerOrange为生产橘子的类 ProducerApple为生产桔子的类 ConsumerApple(消费苹果的类) ConsumerOrange(消费桔子的类)
水果类代码如下
- package com.bankht.producerCustomer;
- public class Fruits {
- private String name;
- public Fruits(String name) {
- this.name = name;
- }
- @Override
- public String toString() {
- return name;
- }
- public Fruits() {
- super();
- }
- }
- package com.bankht.producerCustomer;
- /**
- * @author zhuyong
- * 创建时间:2012-6-6 上午09:46:14
- * 类说明 :
- */
- public class Orange extends Fruits {
- public Orange() {
- super();
- // TODO Auto-generated constructor stub
- }
- public Orange(String name) {
- super(name);
- // TODO Auto-generated constructor stub
- }
- }
- package com.bankht.producerCustomer;
- /**
- * @author zhuyong
- * 创建时间:2012-6-6 上午09:46:14
- */
- public class Apple extends Fruits {
- public Apple() {
- super();
- // TODO Auto-generated constructor stub
- }
- public Apple(String name) {
- super(name);
- // TODO Auto-generated constructor stub
- }
- }
下面是作为缓冲区盘子的代码
- package com.bankht.producerCustomer;
- 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) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- this.notifyAll();// 唤醒生产者
- this.fruites[index++] = goods;
- }
- /**
- * 从临界资源里拿商品,先减一后返回 如果index==0说明, 临界资源数组里面没有商品,不能在消费 消费线程阻塞, 让生产者生产 则让生产者
- *
- * @return
- */
- public synchronized Fruits pop() {
- while (this.index == 0) {
- try {
- this.wait();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- this.notifyAll();// 唤醒消费者
- return fruites[--index];
- }
- /**
- * 看看是不是空了
- *
- * @return
- */
- public synchronized Fruits peek() {
- if (this.index == 0)
- return null;
- else
- return fruites[index - 1];
- }
- public int getIndex() {
- return index;
- }
- public void setIndex(int index) {
- this.index = index;
- }
- public Fruits[] getFruites() {
- return fruites;
- }
- }
下面是生产桔子和消费桔子的代码
- package com.bankht.producerCustomer;
- public class ProducerOrange implements Runnable {
- CriticalResources cr = null;
- public ProducerOrange(CriticalResources cr) {
- super();
- this.cr = cr;
- }
- int count = 5; //做5次
- @Override
- public void run() {
- while(count-->0)
- synchronized (cr) {
- while (cr.peek() != null) {
- try {
- cr.wait();// 该生产这等待
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- Fruits fruits = new Orange("橘子");
- cr.push(fruits);
- System.out.println("橘子生产商生产了" + fruits);
- cr.notifyAll();
- }
- }
- }
- package com.bankht.producerCustomer;
- /**
- * 消费橘子的消费者
- *
- * @author Administrator
- *
- */
- public class ConsumerOrange implements Runnable {
- private CriticalResources cr = null;// 封装一个临界资源对象,以便消费
- public ConsumerOrange(CriticalResources cr) {
- super();
- this.cr = cr;
- }
- int count = 5;
- @Override
- public void run() {
- while (count-- > 0)
- // 如果缓冲区是苹果
- synchronized (cr) {
- while (!(cr.peek() instanceof Orange)) {
- try {
- cr.wait();// 该消费者等待
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- Fruits fruits = cr.pop();
- System.out.println("----橘子消费者消费了-------" + fruits);
- cr.notifyAll();
- }
- }
- }
下面是生产苹果核消费苹果的代码
- package com.bankht.producerCustomer;
- /**
- * 生产苹果的生产者
- *
- * @author Arthur
- *
- */
- public class ProducerApple implements Runnable {
- private CriticalResources cr = null;// 封装一个临界资源对象,以便生产
- public ProducerApple(CriticalResources cr) {
- super();
- this.cr = cr;
- }
- private int count = 5;
- @Override
- public void run() {
- while (count-- > 0)
- synchronized (cr) {
- while ((cr.peek() != null)) {
- try {
- cr.wait();// 缓冲区满,该生产者等待
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- //如果不加锁,此处容易被打断
- Fruits fruits = new Apple("苹果");
- cr.push(fruits);
- System.out.println("苹果生产商生产了" + fruits);
- cr.notifyAll();
- }
- }
- }
- package com.bankht.producerCustomer;
- /**
- * 消费苹果的消费者
- *
- * @author Arthur
- *
- */
- public class ConsumerApple implements Runnable {
- private CriticalResources cr = null;// 封装一个临界资源对象,以便消费
- public ConsumerApple(CriticalResources cr) {
- super();
- this.cr = cr;
- }
- int count = 5;
- @Override
- public void run() {
- while(count-->0)
- synchronized (cr) {
- while (!(cr.peek() instanceof Apple) ) {
- try {
- cr.wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- Fruits fruits = cr.pop();
- System.out.println("----苹果消费者消费了-------" + fruits);
- cr.notifyAll();
- }
- }
- }
客户端代码
- package com.bankht.producerCustomer;
- 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();
- }
- }
运行结果:
- 苹果生产商生产了苹果
- ----苹果消费者消费了-------苹果
- 橘子生产商生产了橘子
- ----橘子消费者消费了-------橘子
- 苹果生产商生产了苹果
- ----苹果消费者消费了-------苹果
- 橘子生产商生产了橘子
- ----橘子消费者消费了-------橘子
- 苹果生产商生产了苹果
- ----苹果消费者消费了-------苹果
- 橘子生产商生产了橘子
- ----橘子消费者消费了-------橘子
- 苹果生产商生产了苹果
- ----苹果消费者消费了-------苹果
- 橘子生产商生产了橘子
- ----橘子消费者消费了-------橘子
- 苹果生产商生产了苹果
- ----苹果消费者消费了-------苹果
- 橘子生产商生产了橘子
- ----橘子消费者消费了-------橘子