生产者模式实现总结

前言

消费者生产者模式是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[]引用  
       }  
    }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值