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 }
  • 相关阅读:
    HDU 1863 畅通工程(Kruskal)
    HDU 1879 继续畅通工程(Kruskra)
    HDU 1102 Constructing Roads(Kruskal)
    POJ 3150 Cellular Automaton(矩阵快速幂)
    POJ 3070 Fibonacci(矩阵快速幂)
    ZOJ 1648 Circuit Board(计算几何)
    ZOJ 3498 Javabeans
    ZOJ 3490 String Successor(模拟)
    Java实现 LeetCode 749 隔离病毒(DFS嵌套)
    Java实现 LeetCode 749 隔离病毒(DFS嵌套)
  • 原文地址:https://www.cnblogs.com/xingmeng/p/3267292.html
Copyright © 2011-2022 走看看