zoukankan      html  css  js  c++  java
  • 生产者模式实现总结1

    前言

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

    一、方式1

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

    (有一篇讲解多线程的非常有名的博客,建议初学多线程的朋友多关注一下,总结网址为:http://lavasoft.blog.51cto.com/62575/27069,顺便感谢一下这些大牛们为吾等小白扫盲!)

    生产者-消费者模型准确说应该是“生产者-消费者-仓储”模型,离开了仓储,生产者消费者模型就显得没有说服力了。
    对于此模型,应该明确一下几点:
    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[]引用  
           }  
        }  
  • 相关阅读:
    cmd 重启oracle服务
    删除父节点同时删除该节点上的所有子节点(oracle)
    安装Oracle提示OracleMTSRecoveryService 已经存在,解决方法
    扩展easyui treegrid 级联选择
    Jetson TX2 不同的工作模式
    CMake版本升级
    高斯混合背景模型运动目标检测
    Windows WSL 安装OpenCV
    C++实现队列
    图像的尺度描述
  • 原文地址:https://www.cnblogs.com/mengyan/p/2664352.html
Copyright © 2011-2022 走看看