生产者模式实现总结

来源:互联网 发布:tensorflow 遗传算法 编辑:程序博客网 时间:2024/05/21 06:19

前言

消费者生产者模式是java中多线程的典型模式,它牵涉到java中多个线程交互的一些方式。下面根据一些典型的实现来说明;

一、方式1

该方式源码出处为:http://eric-619.iteye.com/blog/693681

生产者-消费者模型准确说应该是“生产者-消费者-仓储”模型,离开了仓储,生产者消费者模型就显得没有说服力了。
对于此模型,应该明确一下几点:
1、生产者仅仅在仓储未满时候生产,仓满则停止生产。
2、消费者仅仅在仓储有产品时候才能消费,仓空则等待。
3、当消费者发现仓储没产品可消费时候会通知生产者生产。
4、生产者在生产出可消费产品时候,应该通知等待的消费者去消费
此模型将要结合java.lang.Object的wait与notify、notifyAll方法来实现以上的需求。这是非常重要的。

生产者和消费者通过共享内存的方式进行通信;它们共享的内存是:SyncStack对象;生产者通过SyncStack的同步方法pop向其中添加对象;消费者通过SyncStack的同步方法pop方法在SyncStack对象中获取对象;这是对象间共享内存(或共享数据区域)的方式进行的通信。

关键点详解:

其中的关键是共享内存区域中的两个同步方法,及同步方法中wait()方法的调用;同步保证了对象只能被一个线程占用,wait保证了当线程在等待的过程中释放自己的锁,使得其它对象有机会获得对象的锁;

缺点:

在多个线程进行操作时(有较多生产者和消费者时),使用notifyAll方法会造成不必要进行唤醒的方法进行线程的调度,从而导致不必要的时间花销;

比如一个消费者线程调用了notifyAll(),则会唤醒其它消费者,但是其本意是唤醒生产者来制造物品;由此可见,该方法并没有进行定点的通知。

复制代码
    /*    * 生产者消费者问题其含义就是先生产出了产品,才能拉出去让消费者购买     *    1、多个线程数据共享区域化思想!    *    2、生产者消费者     *         * 二、synchronized加锁:     *      */                  public class ProCon{ //主方法            public static void main(String[] args){      SyncStack stack = new SyncStack();      Consumer p = new Consumer(stack);      Producer c = new Producer(stack);                  new Thread(p).start();      new Thread(c).start();      }      }            class Producer implements Runnable{   //生产者          private SyncStack stack;                public Producer(SyncStack stack){          this.stack = stack;           }                public void run(){          for (int i = 0; i < stack.pro().length; i++){          String product = "产品"+i;          stack.push(product);          System.out.println("生产了: "+product);          try{           Thread.sleep(200);           }catch(InterruptedException e)            {             e.printStackTrace();           }         }      }      }            class Consumer implements Runnable{   //消费者         private SyncStack stack;               public Consumer(SyncStack stack) {         this.stack = stack;          }                  public void run(){         for(int i = 0; i < stack.pro().length; i++){          String product = stack.pop();          System.out.println("消费了: "+product);          try{           Thread.sleep(1000);         }catch(InterruptedException e){           e.printStackTrace();           }          }         }      }            class SyncStack{   // 此类是(本质上:共同访问的)共享数据区域      private String[] str = new String[10];          private int index;                    public synchronized void push(String sst){ //供生产者调用          if(index == sst.length()){           try{            wait();           }catch(InterruptedException e){             e.printStackTrace();            }          }         this.notify(); //唤醒在此对象监视器上等待的单个线程         str[index] = sst;         index++;      }               public synchronized String pop(){   //供消费者调用          if(index == 0){           try{            wait();            }catch (InterruptedException e){             e.printStackTrace();            }         }          notify();          index--;          String product = str[index];          return product;         }                public String[] pro(){ //就是定义一个返回值为数组的方法,返回的是一个String[]引用           return str;   //这是一个String[]引用         }      }  
原创粉丝点击