Java多线程之消费者生产者模式

这个实例应该是学习线程的一个经典例子,生产者和消费者模式。代码写的很好,详细请看内容。
首页 新闻资讯 行业资讯 Java多线程之消费者生产者模式

复制

/*@author shijin  * 生产者与消费者模型中,要保证以下几点:  * 1 同一时间内只能有一个生产者生产     生产方法加锁sychronized  * 2 同一时间内只能有一个消费者消费     消费方法加锁sychronized  * 3 生产者生产的同时消费者不能消费     生产方法加锁sychronized  * 4 消费者消费的同时生产者不能生产     消费方法加锁sychronized  * 5 共享空间空时消费者不能继续消费     消费前循环判断是否为空,空的话将该线程wait,释放锁允许其他同步方法执行  * 6 共享空间满时生产者不能继续生产     生产前循环判断是否为满,满的话将该线程wait,释放锁允许其他同步方法执行     */  //主类  class  ProducerConsumer  {      public static void main(String[] args)       {          StackBasket s = new StackBasket();          Producer p = new Producer(s);          Consumer c = new Consumer(s);          Thread tp = new Thread(p);          Thread tc = new Thread(c);          tp.start();          tc.start();      }  }   //  class Mantou  {      private int id;            Mantou(int id){          this.id = id;      }       public String toString(){          return "Mantou :" + id;      }  }   //共享栈空间  class StackBasket  {      Mantou sm[] = new Mantou[6];      int index = 0;            /**       * show 生产方法.      * show 该方法为同步方法,持有方法锁;      * show 首先循环判断满否,满的话使该线程等待,释放同步方法锁,允许消费;      * show 当不满时首先唤醒正在等待的消费方法,但是也只能让其进入就绪状态,      * show 等生产结束释放同步方法锁后消费才能持有该锁进行消费      * @param m 元素      * @return 没有返回值       */        public synchronized void push(Mantou m){          try{              while(index == sm.length){                  System.out.println("!!!!!!!!!生产满了!!!!!!!!!");                  this.wait();              }              this.notify();          }catch(InterruptedException e){              e.printStackTrace();          }catch(IllegalMonitorStateException e){              e.printStackTrace();          }                    sm[index] = m;          index++;          System.out.println("生产了:" + m + " 共" + index + "个馒头");      }       /**       * show 消费方法      * show 该方法为同步方法,持有方法锁      * show 首先循环判断空否,空的话使该线程等待,释放同步方法锁,允许生产;      * show 当不空时首先唤醒正在等待的生产方法,但是也只能让其进入就绪状态      * show 等消费结束释放同步方法锁后生产才能持有该锁进行生产      * @param b true 表示显示,false 表示隐藏       * @return 没有返回值       */       public synchronized Mantou pop(){          try{              while(index == 0){                  System.out.println("!!!!!!!!!消费光了!!!!!!!!!");                  this.wait();              }              this.notify();          }catch(InterruptedException e){              e.printStackTrace();          }catch(IllegalMonitorStateException e){              e.printStackTrace();          }          index--;          System.out.println("消费了:---------" + sm[index] + " 共" + index + "个馒头");          return sm[index];      }  }   class Producer implements Runnable  {      StackBasket ss = new StackBasket();      Producer(StackBasket ss){          this.ss = ss;      }       /**       * show 生产进程.       */       public void run(){          for(int i = 0;i < 20;i++){              Mantou m = new Mantou(i);              ss.push(m);  //          System.out.println("生产了:" + m + " 共" + ss.index + "个馒头");  //          在上面一行进行测试是不妥的,对index的访问应该在原子操作里,因为可能在push之后此输出之前又消费了,会产生输出混乱              try{                  Thread.sleep((int)(Math.random()*500));              }catch(InterruptedException e){                  e.printStackTrace();              }          }      }  }   class Consumer implements Runnable  {      StackBasket ss = new StackBasket();      Consumer(StackBasket ss){          this.ss = ss;      }       /**       * show 消费进程.      */       public void run(){          for(int i = 0;i < 20;i++){              Mantou m = ss.pop();  //          System.out.println("消费了:---------" + m + " 共" + ss.index + "个馒头");  //  同上  在上面一行进行测试也是不妥的,对index的访问应该在原子操作里,因为可能在pop之后此输出之前又生产了,会产生输出混乱              try{                  Thread.sleep((int)(Math.random()*1000));              }catch(InterruptedException e){                  e.printStackTrace();              }          }      }  }
  • 1.

  • 2.

  • 3.

  • 4.

  • 5.

  • 6.

  • 7.

  • 8.

  • 9.

  • 10.

  • 11.

  • 12.

  • 13.

  • 14.

  • 15.

  • 16.

  • 17.

  • 18.

  • 19.

  • 20.

  • 21.

  • 22.

  • 23.

  • 24.

  • 25.

  • 26.

  • 27.

  • 28.

  • 29.

  • 30.

  • 31.

  • 32.

  • 33.

  • 34.

  • 35.

  • 36.

  • 37.

  • 38.

  • 39.

  • 40.

  • 41.

  • 42.

  • 43.

  • 44.

  • 45.

  • 46.

  • 47.

  • 48.

  • 49.

  • 50.

  • 51.

  • 52.

  • 53.

  • 54.

  • 55.

  • 56.

  • 57.

  • 58.

  • 59.

  • 60.

  • 61.

  • 62.

  • 63.

  • 64.

  • 65.

  • 66.

  • 67.

  • 68.

  • 69.

  • 70.

  • 71.

  • 72.

  • 73.

  • 74.

  • 75.

  • 76.

  • 77.

  • 78.

  • 79.

  • 80.

  • 81.

  • 82.

  • 83.

  • 84.

  • 85.

  • 86.

  • 87.

  • 88.

  • 89.

  • 90.

  • 91.

  • 92.

  • 93.

  • 94.

  • 95.

  • 96.

  • 97.

  • 98.

  • 99.

  • 100.

  • 101.

  • 102.

  • 103.

  • 104.

  • 105.

  • 106.

  • 107.

  • 108.

  • 109.

  • 110.

  • 111.

  • 112.

  • 113.

  • 114.

  • 115.

  • 116.

  • 117.

  • 118.

  • 119.

  • 120.

  • 121.

  • 122.

  • 123.

  • 124.

  • 125.

  • 126.

  • 127.

  • 128.

  • 129.

  • 130.

  • 131.

  • 132.

  • 133.

  • 134.

  • 135.

  • 136.

  • 137.

  • 138.

  • 139.

  • 140.

  • 141.

  • 142.

  • 143.

  • 144.

  • 145.

  • 146.

  • 147.

  • 148.

 原文链接:http://blog.csdn.net/shijinupc/article/details/7250407

【编辑推荐】

  1. 深入理解Java对象序列化

  2. 菜鸟入门Java语言学习的要点

  3. 如何优化Java程序设计和编码提高性能

  4. Java自定义范型的应用技巧

  5. 深入注解:在Java中设计和使用自己的注解

16    2012-02-14 12:31:27    Java