zoukankan      html  css  js  c++  java
  • java多线程之消费者生产者模式

    1. /*@author shijin 
    2. * 生产者与消费者模型中,要保证以下几点: 
    3. * 1 同一时间内只能有一个生产者生产     生产方法加锁sychronized 
    4. * 2 同一时间内只能有一个消费者消费     消费方法加锁sychronized 
    5. * 3 生产者生产的同时消费者不能消费     生产方法加锁sychronized 
    6. * 4 消费者消费的同时生产者不能生产     消费方法加锁sychronized 
    7. * 5 共享空间空时消费者不能继续消费     消费前循环判断是否为空,空的话将该线程wait,释放锁允许其他同步方法执行 
    8. * 6 共享空间满时生产者不能继续生产     生产前循环判断是否为满,满的话将该线程wait,释放锁允许其他同步方法执行    
    9. */  
    10.   
    11. //主类   
    12. class  ProducerConsumer  
    13. {  
    14.     public static void main(String[] args)   
    15.     {  
    16.         StackBasket s = new StackBasket();  
    17.         Producer p = new Producer(s);  
    18.         Consumer c = new Consumer(s);  
    19.         Thread tp = new Thread(p);  
    20.         Thread tc = new Thread(c);  
    21.         tp.start();  
    22.         tc.start();  
    23.     }  
    24. }  
    25.   
    26. //   
    27. class Mantou  
    28. {  
    29.     private int id;  
    30.       
    31.     Mantou(int id){  
    32.         this.id = id;  
    33.     }  
    34.   
    35.     public String toString(){  
    36.         return "Mantou :" + id;  
    37.     }  
    38. }  
    39.   
    40. //共享栈空间   
    41. class StackBasket  
    42. {  
    43.     Mantou sm[] = new Mantou[6];  
    44.     int index = 0;  
    45.       
    46.     /**  
    47.     * show 生产方法. 
    48.     * show 该方法为同步方法,持有方法锁; 
    49.     * show 首先循环判断满否,满的话使该线程等待,释放同步方法锁,允许消费; 
    50.     * show 当不满时首先唤醒正在等待的消费方法,但是也只能让其进入就绪状态, 
    51.     * show 等生产结束释放同步方法锁后消费才能持有该锁进行消费 
    52.     * @param m 元素 
    53.     * @return 没有返回值  
    54.     */   
    55.   
    56.     public synchronized void push(Mantou m){  
    57.         try{  
    58.             while(index == sm.length){  
    59.                 System.out.println("!!!!!!!!!生产满了!!!!!!!!!");  
    60.                 this.wait();  
    61.             }  
    62.             this.notify();  
    63.         }catch(InterruptedException e){  
    64.             e.printStackTrace();  
    65.         }catch(IllegalMonitorStateException e){  
    66.             e.printStackTrace();  
    67.         }  
    68.           
    69.         sm[index] = m;  
    70.         index++;  
    71.         System.out.println("生产了:" + m + " 共" + index + "个馒头");  
    72.     }  
    73.   
    74.     /**  
    75.     * show 消费方法 
    76.     * show 该方法为同步方法,持有方法锁 
    77.     * show 首先循环判断空否,空的话使该线程等待,释放同步方法锁,允许生产; 
    78.     * show 当不空时首先唤醒正在等待的生产方法,但是也只能让其进入就绪状态 
    79.     * show 等消费结束释放同步方法锁后生产才能持有该锁进行生产 
    80.     * @param b true 表示显示,false 表示隐藏  
    81.     * @return 没有返回值  
    82.     */   
    83.     public synchronized Mantou pop(){  
    84.         try{  
    85.             while(index == 0){  
    86.                 System.out.println("!!!!!!!!!消费光了!!!!!!!!!");  
    87.                 this.wait();  
    88.             }  
    89.             this.notify();  
    90.         }catch(InterruptedException e){  
    91.             e.printStackTrace();  
    92.         }catch(IllegalMonitorStateException e){  
    93.             e.printStackTrace();  
    94.         }  
    95.         index--;  
    96.         System.out.println("消费了:---------" + sm[index] + " 共" + index + "个馒头");  
    97.         return sm[index];  
    98.     }  
    99. }  
    100.   
    101. class Producer implements Runnable  
    102. {  
    103.     StackBasket ss = new StackBasket();  
    104.     Producer(StackBasket ss){  
    105.         this.ss = ss;  
    106.     }  
    107.   
    108.     /**  
    109.     * show 生产进程.  
    110.     */   
    111.     public void run(){  
    112.         for(int i = 0;i < 20;i++){  
    113.             Mantou m = new Mantou(i);  
    114.             ss.push(m);  
    115. //          System.out.println("生产了:" + m + " 共" + ss.index + "个馒头");   
    116. //          在上面一行进行测试是不妥的,对index的访问应该在原子操作里,因为可能在push之后此输出之前又消费了,会产生输出混乱   
    117.             try{  
    118.                 Thread.sleep((int)(Math.random()*500));  
    119.             }catch(InterruptedException e){  
    120.                 e.printStackTrace();  
    121.             }  
    122.         }  
    123.     }  
    124. }  
    125.   
    126. class Consumer implements Runnable  
    127. {  
    128.     StackBasket ss = new StackBasket();  
    129.     Consumer(StackBasket ss){  
    130.         this.ss = ss;  
    131.     }  
    132.   
    133.     /**  
    134.     * show 消费进程. 
    135.     */   
    136.     public void run(){  
    137.         for(int i = 0;i < 20;i++){  
    138.             Mantou m = ss.pop();  
    139. //          System.out.println("消费了:---------" + m + " 共" + ss.index + "个馒头");   
    140. //  同上  在上面一行进行测试也是不妥的,对index的访问应该在原子操作里,因为可能在pop之后此输出之前又生产了,会产生输出混乱   
    141.             try{  
    142.                 Thread.sleep((int)(Math.random()*1000));  
    143.             }catch(InterruptedException e){  
    144.                 e.printStackTrace();  
    145.             }  
    146.         }  
    147.     }  
    148. }  
  • 相关阅读:
    C#中IPAddress转换成整型int
    没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG))
    VB.NET或C#报错:You must hava a license to use this ActiveX control.
    c#几种随机数组和数组乱序
    C#封装的websocket协议类
    VB生成条形码(EAN-13)
    VB控件间的拖放
    VB用API模拟截屏键PrintScreen
    VB读写进程的内存
    几个VB常见又内涵的错误
  • 原文地址:https://www.cnblogs.com/kaikailele/p/4009262.html
Copyright © 2011-2022 走看看