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

在《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;
	}

	@Override
	public 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;
		else
			return 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次

	@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();
		        }

	}

}

/**
 * 消费橘子的消费者
 * 
 * @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 arthur.thread.producerandcoustomer; 
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){
                            //响应中断
                        }
                    } /如果不加锁,此处容易被打断
                    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;

    @Override
    public 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();
    }

}

运行结果

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

 
 
 
 
 
 
 

                
  • 14
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郭梧悠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值