zoukankan      html  css  js  c++  java
  • 多线程学习-基础(十二)生产者消费者模型:wait(),sleep(),notify()实现

    一、多线程模型一:生产者消费者模型

      (1)模型图:(从网上找的图,清晰明了)

    (2)生产者消费者模型原理说明:

      这个模型核心是围绕着一个“仓库”的概念,生产者消费者都是围绕着:“仓库”来进行操作,一个仓库同时只能被一个生产者线程或一个消费者线程所操作,synchronized锁住的也是这个仓库,仓库是一个容器,所以会有边界值,0和仓库可存放上限,在这个上限内,可以设置多种级别,不同的级别可以执行不同的策略流程。

    (3)本案例使用知识点:

      Thread.currentThread().interrupt();//中断线程

      this.notify();//唤醒其他线程

      this.wait();//停止出货

      Thread.sleep(1000);//放置一个线程占用cpu过久

           这些知识点都是多线程的基础知识点,以后会尝试使用:BlockingQueue,线程池来扩展这些简单的案例,个人觉得,先掌握好简单的使用,然后再在其上扩展,记忆会比较深刻一点。

     二、案例源码

       案例说明:

         本案例有:产品类Product  ,仓库类Warehouse  , 生产者线程(实现Runnable)Producer   , 消费者线程(实现Runnable)Consumer      ,以及一个启动类ThreadStart

        好了,直接贴出代码吧。

    产品类Product 

     1 package com.jason.proCusModels;
     2 /**
     3  * 产品类
     4  * @function  
     5  * @author 小风微凉
     6  * @time  2018-4-26 下午8:00:40
     7  */
     8 public class Product {
     9     //产品名称
    10     private String pName;
    11     //产品编号
    12     private String proNo;
    13     public Product(String pName,String proNo){
    14         this.pName=pName;
    15         this.proNo=proNo;
    16     }
    17     //设置getter方法
    18     public String getpName() {
    19         return pName;
    20     }
    21     public String getProNo() {
    22         return proNo;
    23     }
    24     //重写toString方法
    25     @Override
    26     public String toString() {
    27         return "产品名称:"+this.pName+",产品编号:"+this.proNo;
    28     }
    29 }

     仓库类Warehouse

     1 package com.jason.proCusModels;
     2 import java.util.ArrayList;
     3 import java.util.List;
     4 /**
     5  * 仓库类
     6  * @function  
     7  * @author 小风微凉
     8  * @time  2018-4-26 下午7:59:34
     9  */
    10 public class Warehouse {
    11     //仓库名称
    12     private String name;
    13     //仓库最大容量上限
    14     private int MAX_COUNT=100;
    15     //设置仓库货物预警下限:此处可以加设进货策略,不同的缺货程度,设置不同的进货速度(以后再补充)
    16     private int MIN_COUNT=20;
    17     //仓库存放商品的容器
    18     public static  List<Product> proList;
    19     //静态块
    20     static{
    21         proList=new ArrayList<Product>();
    22     }
    23     //构造器
    24     public Warehouse(String name){
    25         this.name=name;
    26     }
    27     /**
    28      * 仓库进货
    29      * @param count 进货数量
    30      */
    31     public synchronized void Purchase(int count){        
    32         //判断当前货物+count是否超过上限     如果超过,则停止进货   只允许出货
    33         int currCount=proList.size();
    34         if(currCount+count>MAX_COUNT){
    35             this.notify();//唤醒其他线程
    36             try {
    37                 System.out.println(Thread.currentThread().getName()+"准备进货:"+count+"个产品,当前仓库货物有:"+currCount+"个,【货物超过仓库存放上限:"+MAX_COUNT+"】,已经停止进货");
    38                 this.wait();//停止进货
    39             } catch (InterruptedException e) {
    40                 e.printStackTrace();
    41                 Thread.currentThread().interrupt();//中断线程
    42             }
    43         }else{//判断:当前货物+count没有超过上限   则可以继续进货
    44             if(currCount<=MIN_COUNT){
    45                 System.out.println("当前仓库剩余货物数量,在最低警戒线一下,请抓紧时间补货!!!!!!!");
    46             }
    47             //开始进货
    48             for(int i=0;i<count;i++){
    49                 //拿到产品
    50                 Product prod=new Product("IphoneX", "*");//编号随意,暂时不会用到
    51                 //入库
    52                 proList.add(prod);                
    53             }
    54             System.out.println(Thread.currentThread().getName()+"准备进货:"+count+"个产品,当前仓库货物有:"+currCount+"个,进货后仓库总有:"+proList.size());
    55         }
    56         try {
    57             Thread.sleep(1000);//放置一个线程占用cpu过久
    58         } catch (InterruptedException e) {
    59             e.printStackTrace();
    60         }
    61     } 
    62     /**
    63      * 仓库出货
    64      * @param count·出货数量
    65      */
    66     public  synchronized void Shipments(int count){
    67         //如果当前仓库货物余货为0  或者出货数量<count  则停止出货   开始进货
    68         int currCount=proList.size();
    69         if(currCount==0 || currCount<count){
    70             this.notify();//唤醒其他线程
    71             try {
    72                 System.out.println(Thread.currentThread().getName()+"准备出货:"+count+"个产品,当前仓库货物有:"+currCount+"个,【货物短缺,请尽快进货】,已经停止出货");
    73                 this.wait();//停止出货
    74             } catch (InterruptedException e) {
    75                 e.printStackTrace();
    76                 Thread.currentThread().interrupt();//中断线程
    77             }
    78         }else{//仓库货物充足,可继续出货
    79             //出货
    80             proList=proList.subList(count, proList.size());
    81             System.out.println(Thread.currentThread().getName()+"准备出货:"+count+"个产品,当前仓库货物有:"+currCount+"个,出货后仓库总有:"+proList.size());
    82         }
    83         try {
    84             Thread.sleep(1000);//放置一个线程占用cpu过久
    85         } catch (InterruptedException e) {
    86             e.printStackTrace();
    87         }
    88     }
    89     /**
    90      * 拿到仓库容器
    91      * @return
    92      */
    93     public static List<Product> getProList() {
    94         return proList;
    95     }
    96 }

     生产者线程(实现Runnable)Producer

     1 package com.jason.proCusModels;
     2 /**
     3  * 生产者类(线程)
     4  * @function  
     5  * @author 小风微凉
     6  * @time  2018-4-26 下午7:57:47
     7  */
     8 public class Producer implements Runnable{
     9     //生产者名称
    10     private String name;
    11     //仓库对象
    12     private Warehouse whose;//这样写只是为了让关系更加清晰   实际仓库容器:Warehouse.proList    
    13     //消费产品数量
    14     private int threadCount;
    15     //构造器
    16     public Producer(String name,int threadCount,Warehouse whose){
    17         this.name=name;
    18         this.whose=whose;
    19         this.threadCount=threadCount;
    20     }
    21     public void run() {
    22         Thread.currentThread().setName(this.name);
    23         //开始进货
    24         while(true){
    25             whose.Purchase(threadCount);
    26         }        
    27     }
    28 }

    消费者线程(实现Runnable)Consumer  

     1 package com.jason.proCusModels;
     2 /**
     3  * 消费者类(线程)
     4  * @function  
     5  * @author 小风微凉
     6  * @time  2018-4-26 下午7:58:59
     7  */
     8 public class Consumer  implements Runnable{
     9     //消费者名称
    10     private String name;
    11     //仓库对象
    12     private Warehouse whose;//这样写只是为了让关系更加清晰   实际仓库容器:Warehouse.proList    
    13     //消费产品数量
    14     private int threadCount;
    15     //构造器
    16     public Consumer(String name,int threadCount,Warehouse whose){
    17         this.name=name;
    18         this.whose=whose;
    19         this.threadCount=threadCount;
    20     }
    21     public void run() {
    22         Thread.currentThread().setName(this.name);
    23         //开始出货
    24         while(true){
    25             whose.Shipments(threadCount);
    26         }
    27     }
    28 }

    一个启动类ThreadStart

     1 package com.jason.proCusModels;
     2 /**
     3  * 多线程学习
     4  * @function  生产者消费者模型启动类
     5  * @author 小风微凉
     6  * @time  2018-4-26 下午8:51:56
     7  */
     8 public class ThreadStart {
     9     /**
    10      * 启动项
    11      * @param args
    12      */
    13     public static void main(String[] args) {
    14         //创建一个仓库
    15         Warehouse whose=new Warehouse("1号仓库");
    16         //创建10个生产者线程
    17         for(int i=1;i<=10;i++){
    18             new Thread(new Producer(i+"号生产者",(int)(Math.random()*10+1),whose)).start();
    19         }
    20         //创建15个消费者线程
    21         for(int i=1;i<=15;i++){
    22             new Thread(new Consumer(i+"号消费者",(int)(Math.random()*10+1),whose)).start();
    23         }
    24     }
    25 }

    运行结果:(仅截取部分结果)

    当前仓库剩余货物数量,在最低警戒线一下,请抓紧时间补货!!!!!!!
    1号生产者准备进货:6个产品,当前仓库货物有:0个,进货后仓库总有:6
    12号消费者准备出货:1个产品,当前仓库货物有:6个,出货后仓库总有:5
    15号消费者准备出货:3个产品,当前仓库货物有:5个,出货后仓库总有:2
    14号消费者准备出货:3个产品,当前仓库货物有:2个,【货物短缺,请尽快进货】,已经停止出货
    11号消费者准备出货:9个产品,当前仓库货物有:2个,【货物短缺,请尽快进货】,已经停止出货
    13号消费者准备出货:2个产品,当前仓库货物有:2个,出货后仓库总有:0
    10号消费者准备出货:6个产品,当前仓库货物有:0个,【货物短缺,请尽快进货】,已经停止出货
    4号消费者准备出货:1个产品,当前仓库货物有:0个,【货物短缺,请尽快进货】,已经停止出货
    6号消费者准备出货:2个产品,当前仓库货物有:0个,【货物短缺,请尽快进货】,已经停止出货
    9号消费者准备出货:2个产品,当前仓库货物有:0个,【货物短缺,请尽快进货】,已经停止出货
    8号消费者准备出货:9个产品,当前仓库货物有:0个,【货物短缺,请尽快进货】,已经停止出货
    5号消费者准备出货:5个产品,当前仓库货物有:0个,【货物短缺,请尽快进货】,已经停止出货
    7号消费者准备出货:5个产品,当前仓库货物有:0个,【货物短缺,请尽快进货】,已经停止出货
    3号消费者准备出货:4个产品,当前仓库货物有:0个,【货物短缺,请尽快进货】,已经停止出货
    2号消费者准备出货:3个产品,当前仓库货物有:0个,【货物短缺,请尽快进货】,已经停止出货
    1号消费者准备出货:5个产品,当前仓库货物有:0个,【货物短缺,请尽快进货】,已经停止出货
    当前仓库剩余货物数量,在最低警戒线一下,请抓紧时间补货!!!!!!!
    10号生产者准备进货:1个产品,当前仓库货物有:0个,进货后仓库总有:1
    当前仓库剩余货物数量,在最低警戒线一下,请抓紧时间补货!!!!!!!
    9号生产者准备进货:3个产品,当前仓库货物有:1个,进货后仓库总有:4
    当前仓库剩余货物数量,在最低警戒线一下,请抓紧时间补货!!!!!!!
    8号生产者准备进货:5个产品,当前仓库货物有:4个,进货后仓库总有:9
    当前仓库剩余货物数量,在最低警戒线一下,请抓紧时间补货!!!!!!!
    8号生产者准备进货:5个产品,当前仓库货物有:9个,进货后仓库总有:14
    当前仓库剩余货物数量,在最低警戒线一下,请抓紧时间补货!!!!!!!
    7号生产者准备进货:9个产品,当前仓库货物有:14个,进货后仓库总有:23
    6号生产者准备进货:9个产品,当前仓库货物有:23个,进货后仓库总有:32
    5号生产者准备进货:1个产品,当前仓库货物有:32个,进货后仓库总有:33
    4号生产者准备进货:8个产品,当前仓库货物有:33个,进货后仓库总有:41
    3号生产者准备进货:9个产品,当前仓库货物有:41个,进货后仓库总有:50
    2号生产者准备进货:8个产品,当前仓库货物有:50个,进货后仓库总有:58
    3号生产者准备进货:9个产品,当前仓库货物有:58个,进货后仓库总有:67
    4号生产者准备进货:8个产品,当前仓库货物有:67个,进货后仓库总有:75
    5号生产者准备进货:1个产品,当前仓库货物有:75个,进货后仓库总有:76
    6号生产者准备进货:9个产品,当前仓库货物有:76个,进货后仓库总有:85
    6号生产者准备进货:9个产品,当前仓库货物有:85个,进货后仓库总有:94
    6号生产者准备进货:9个产品,当前仓库货物有:94个,【货物超过仓库存放上限:100】,已经停止进货
    7号生产者准备进货:9个产品,当前仓库货物有:94个,【货物超过仓库存放上限:100】,已经停止进货
    8号生产者准备进货:5个产品,当前仓库货物有:94个,进货后仓库总有:99
    9号生产者准备进货:3个产品,当前仓库货物有:99个,【货物超过仓库存放上限:100】,已经停止进货
    10号生产者准备进货:1个产品,当前仓库货物有:99个,进货后仓库总有:100
    2号消费者准备出货:3个产品,当前仓库货物有:100个,出货后仓库总有:97
    2号消费者准备出货:3个产品,当前仓库货物有:97个,出货后仓库总有:94
    3号消费者准备出货:4个产品,当前仓库货物有:94个,出货后仓库总有:90
    3号消费者准备出货:4个产品,当前仓库货物有:90个,出货后仓库总有:86
    3号消费者准备出货:4个产品,当前仓库货物有:86个,出货后仓库总有:82
    3号消费者准备出货:4个产品,当前仓库货物有:82个,出货后仓库总有:78
    5号消费者准备出货:5个产品,当前仓库货物有:78个,出货后仓库总有:73

    说明:这个用不着分析了,过程和结果很明显,思路还处于初级阶段,以后会慢慢改进优化。如果您有好的建议,欢迎指正,交流促进进步!

  • 相关阅读:
    python
    爬虫
    python 自动登录
    day22 cookie session 中间件 Form
    day10进程、异步IO、
    python第五课
    day21
    day20 Django
    day 19
    day18
  • 原文地址:https://www.cnblogs.com/newwind/p/8955201.html
Copyright © 2011-2022 走看看