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


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

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

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

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

    水果类代码如下

    [java] view plain copy
     
    1. package com.bankht.producerCustomer;  
    2.   
    3. public class Fruits {  
    4.     private String name;  
    5.   
    6.     public Fruits(String name) {  
    7.         this.name = name;  
    8.     }  
    9.   
    10.     @Override  
    11.     public String toString() {  
    12.         return name;  
    13.     }  
    14.   
    15.     public Fruits() {  
    16.         super();  
    17.     }  
    18.   
    19. }  

    [java] view plain copy
     
    1. package com.bankht.producerCustomer;  
    2.   
    3. /** 
    4.  * @author zhuyong  
    5.  * 创建时间:2012-6-6 上午09:46:14 
    6.  * 类说明 : 
    7.  */  
    8. public class Orange extends Fruits {  
    9.   
    10.     public Orange() {  
    11.         super();  
    12.         // TODO Auto-generated constructor stub  
    13.     }  
    14.   
    15.     public Orange(String name) {  
    16.         super(name);  
    17.         // TODO Auto-generated constructor stub  
    18.     }  
    19.       
    20. }  
    [java] view plain copy
     
    1. package com.bankht.producerCustomer;  
    2.   
    3. /** 
    4.  * @author zhuyong  
    5.  * 创建时间:2012-6-6 上午09:46:14 
    6.  */  
    7. public class Apple extends Fruits {  
    8.   
    9.     public Apple() {  
    10.         super();  
    11.         // TODO Auto-generated constructor stub  
    12.     }  
    13.   
    14.     public Apple(String name) {  
    15.         super(name);  
    16.         // TODO Auto-generated constructor stub  
    17.     }  
    18.       
    19. }  


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

    [java] view plain copy
     
    1. package com.bankht.producerCustomer;  
    2.   
    3. public class CriticalResources {  
    4.     private int index = 0;  
    5.     private static Fruits[] fruites = new Fruits[1];// 默认临界区有五个商品  
    6.     private ProducerApple pa = new ProducerApple(this);  
    7.     private ProducerOrange po = new ProducerOrange(this);  
    8.     private ConsumerApple ca = new ConsumerApple(this);  
    9.     private ConsumerOrange co = new ConsumerOrange(this);  
    10.   
    11.     /** 
    12.      * 向临界资源里添加商品 利用synchronized关键字实现同步 添加后数组指针+1 
    13.      * 如果临界资源数组里面装满了商品不能再生产,则生产线程等待以便让消费者消费 
    14.      *  
    15.      * @param goods 
    16.      */  
    17.     public synchronized void push(Fruits goods) {  
    18.         //  
    19.         while (this.index == this.fruites.length) {  
    20.             try {  
    21.                 this.wait();  
    22.             } catch (InterruptedException e) {  
    23.                 // TODO Auto-generated catch block  
    24.                 e.printStackTrace();  
    25.             }  
    26.         }  
    27.   
    28.         this.notifyAll();// 唤醒生产者  
    29.         this.fruites[index++] = goods;  
    30.   
    31.     }  
    32.   
    33.     /** 
    34.      * 从临界资源里拿商品,先减一后返回 如果index==0说明, 临界资源数组里面没有商品,不能在消费 消费线程阻塞, 让生产者生产 则让生产者 
    35.      *  
    36.      * @return 
    37.      */  
    38.     public synchronized Fruits pop() {  
    39.         while (this.index == 0) {  
    40.             try {  
    41.                 this.wait();  
    42.             } catch (InterruptedException e) {  
    43.                 // TODO Auto-generated catch block  
    44.                 e.printStackTrace();  
    45.             }  
    46.         }  
    47.   
    48.         this.notifyAll();// 唤醒消费者  
    49.         return fruites[--index];  
    50.   
    51.     }  
    52.   
    53.     /** 
    54.      * 看看是不是空了 
    55.      *  
    56.      * @return 
    57.      */  
    58.     public synchronized Fruits peek() {  
    59.         if (this.index == 0)  
    60.             return null;  
    61.         else  
    62.             return fruites[index - 1];  
    63.     }  
    64.   
    65.     public int getIndex() {  
    66.         return index;  
    67.     }  
    68.   
    69.     public void setIndex(int index) {  
    70.         this.index = index;  
    71.     }  
    72.   
    73.     public Fruits[] getFruites() {  
    74.         return fruites;  
    75.     }  
    76.   
    77. }  


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

    [java] view plain copy
     
    1. package com.bankht.producerCustomer;  
    2.   
    3. public class ProducerOrange implements Runnable {  
    4.     CriticalResources cr = null;  
    5.   
    6.     public ProducerOrange(CriticalResources cr) {  
    7.         super();  
    8.         this.cr = cr;  
    9.     }  
    10.     int count = 5; //做5次  
    11.   
    12.     @Override  
    13.     public void run() {  
    14.          while(count-->0)  
    15.                 synchronized (cr) {  
    16.                     while (cr.peek() != null) {  
    17.                         try {  
    18.                             cr.wait();// 该生产这等待  
    19.                         } catch (InterruptedException e) {  
    20.                             // TODO Auto-generated catch block  
    21.                             e.printStackTrace();  
    22.                         }  
    23.                     }  
    24.                     Fruits fruits = new Orange("橘子");  
    25.                     cr.push(fruits);  
    26.                     System.out.println("橘子生产商生产了" + fruits);  
    27.                     cr.notifyAll();  
    28.                 }  
    29.   
    30.     }  
    31.   
    32. }  


     

    [java] view plain copy
     
    1. package com.bankht.producerCustomer;  
    2.   
    3. /** 
    4.  * 消费橘子的消费者 
    5.  *  
    6.  * @author Administrator 
    7.  *  
    8.  */  
    9. public class ConsumerOrange implements Runnable {  
    10.   
    11.     private CriticalResources cr = null;// 封装一个临界资源对象,以便消费  
    12.   
    13.     public ConsumerOrange(CriticalResources cr) {  
    14.         super();  
    15.         this.cr = cr;  
    16.     }  
    17.   
    18.     int count = 5;  
    19.   
    20.     @Override  
    21.     public void run() {  
    22.   
    23.         while (count-- > 0)  
    24.             // 如果缓冲区是苹果  
    25.             synchronized (cr) {  
    26.                 while (!(cr.peek() instanceof Orange)) {  
    27.                     try {  
    28.                         cr.wait();// 该消费者等待  
    29.                     } catch (InterruptedException e) {  
    30.                         // TODO Auto-generated catch block  
    31.                         e.printStackTrace();  
    32.                     }  
    33.                 }  
    34.                 Fruits fruits = cr.pop();  
    35.   
    36.                 System.out.println("----橘子消费者消费了-------" + fruits);  
    37.                 cr.notifyAll();  
    38.             }  
    39.   
    40.     }  
    41.   
    42. }  


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

    [java] view plain copy
     
    1. package com.bankht.producerCustomer;  
    2.   
    3.   
    4. /** 
    5.  * 生产苹果的生产者 
    6.  *  
    7.  * @author Arthur 
    8.  *  
    9.  */  
    10. public class ProducerApple implements Runnable {  
    11.     private CriticalResources cr = null;// 封装一个临界资源对象,以便生产  
    12.   
    13.     public ProducerApple(CriticalResources cr) {  
    14.         super();  
    15.         this.cr = cr;  
    16.     }  
    17.   
    18.     private int count = 5;  
    19.   
    20.     @Override  
    21.     public void run() {  
    22.         while (count-- > 0)  
    23.             synchronized (cr) {  
    24.                 while ((cr.peek() != null)) {  
    25.                     try {  
    26.                         cr.wait();// 缓冲区满,该生产者等待  
    27.                     } catch (InterruptedException e) {  
    28.                         e.printStackTrace();  
    29.                     }  
    30.                 }  
    31.                 //如果不加锁,此处容易被打断  
    32.                 Fruits fruits = new Apple("苹果");  
    33.                 cr.push(fruits);  
    34.                 System.out.println("苹果生产商生产了" + fruits);  
    35.                 cr.notifyAll();  
    36.             }  
    37.   
    38.     }  
    39.   
    40. }  


     

    [java] view plain copy
     
    1. package com.bankht.producerCustomer;  
    2.   
    3. /** 
    4.  * 消费苹果的消费者 
    5.  *  
    6.  * @author Arthur 
    7.  *  
    8.  */  
    9. public class ConsumerApple implements Runnable {  
    10.     private CriticalResources cr = null;// 封装一个临界资源对象,以便消费  
    11.   
    12.     public ConsumerApple(CriticalResources cr) {  
    13.         super();  
    14.         this.cr = cr;  
    15.     }  
    16. int count = 5;  
    17.     @Override  
    18.     public void run() {  
    19.          while(count-->0)  
    20.                 synchronized (cr) {  
    21.                     while (!(cr.peek() instanceof Apple) ) {  
    22.                         try {  
    23.                             cr.wait();  
    24.                         } catch (InterruptedException e) {  
    25.                             e.printStackTrace();  
    26.                         }  
    27.                     }  
    28.                     Fruits fruits = cr.pop();  
    29.   
    30.                     System.out.println("----苹果消费者消费了-------" + fruits);  
    31.                     cr.notifyAll();  
    32.                       
    33.                 }  
    34.   
    35.   
    36.     }  
    37. }  


    客户端代码

    [java] view plain copy
     
    1. package com.bankht.producerCustomer;  
    2.   
    3. public class Client {  
    4.   
    5.       /** 
    6.      * @param args 
    7.      */  
    8.     public static void main(String[] args) {  
    9.         CriticalResources cr = new CriticalResources();  
    10.         // 生产苹果实例  
    11.         ProducerApple appleP = new ProducerApple(cr);  
    12.         // 消费苹果实例  
    13.         ConsumerApple appleC = new ConsumerApple(cr);  
    14.   
    15.         // 橘子生产者实例  
    16.         ProducerOrange orangeP = new ProducerOrange(cr);  
    17.         // 橘子消费者实例  
    18.         ConsumerOrange orangeC = new ConsumerOrange(cr);  
    19.         // 生产苹果线程  
    20.         Thread pThread = new Thread(appleP);  
    21.         // 消费苹果线程  
    22.         Thread cThread = new Thread(appleC);  
    23.         // 生产橘子线程  
    24.         Thread pt = new Thread(orangeP);  
    25.         // 消费橘子线程  
    26.         Thread ct = new Thread(orangeC);  
    27.   
    28.          
    29.   
    30.         pThread.start();  
    31.         cThread.start();  
    32.         pt.start();  
    33.         ct.start();  
    34.     }  
    35.   
    36. }  


    运行结果:

    [html] view plain copy
     
    1. 苹果生产商生产了苹果  
    2. ----苹果消费者消费了-------苹果  
    3. 橘子生产商生产了橘子  
    4. ----橘子消费者消费了-------橘子  
    5. 苹果生产商生产了苹果  
    6. ----苹果消费者消费了-------苹果  
    7. 橘子生产商生产了橘子  
    8. ----橘子消费者消费了-------橘子  
    9. 苹果生产商生产了苹果  
    10. ----苹果消费者消费了-------苹果  
    11. 橘子生产商生产了橘子  
    12. ----橘子消费者消费了-------橘子  
    13. 苹果生产商生产了苹果  
    14. ----苹果消费者消费了-------苹果  
    15. 橘子生产商生产了橘子  
    16. ----橘子消费者消费了-------橘子  
    17. 苹果生产商生产了苹果  
    18. ----苹果消费者消费了-------苹果  
    19. 橘子生产商生产了橘子  
    20. ----橘子消费者消费了-------橘子  
  • 相关阅读:
    winform 监视DataGridView的滚动条,加载数据
    SQL 自动生成行号
    SQL 删除重复的数据(多个字段判断),只保留一条数据
    C# 一个简单的 工厂模式 例子
    winform 重写TextBox的OnTextChanged方法(事件)
    winform 给文本框加载内容的时候 始终让文本框的滚动条到底(允许显示多行Multiline=True)
    winform 制定DataGridViewTextColumn列(更改DataGridView的Cell的状态很有用)
    winform 使用委托 实现多线程访问控件
    C# 一个简单的递归函数和 两个List<T> 合并
    ADO.NET  把数据库A的某表的数据内容复制到数据库B的某表内
  • 原文地址:https://www.cnblogs.com/du-0210/p/8431617.html
Copyright © 2020-2023  润新知