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

  (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. 当前仓库剩余货物数量,在最低警戒线一下,请抓紧时间补货!!!!!!!
  2. 1号生产者准备进货:6个产品,当前仓库货物有:0个,进货后仓库总有:6
  3. 12号消费者准备出货:1个产品,当前仓库货物有:6个,出货后仓库总有:5
  4. 15号消费者准备出货:3个产品,当前仓库货物有:5个,出货后仓库总有:2
  5. 14号消费者准备出货:3个产品,当前仓库货物有:2个,【货物短缺,请尽快进货】,已经停止出货
  6. 11号消费者准备出货:9个产品,当前仓库货物有:2个,【货物短缺,请尽快进货】,已经停止出货
  7. 13号消费者准备出货:2个产品,当前仓库货物有:2个,出货后仓库总有:0
  8. 10号消费者准备出货:6个产品,当前仓库货物有:0个,【货物短缺,请尽快进货】,已经停止出货
  9. 4号消费者准备出货:1个产品,当前仓库货物有:0个,【货物短缺,请尽快进货】,已经停止出货
  10. 6号消费者准备出货:2个产品,当前仓库货物有:0个,【货物短缺,请尽快进货】,已经停止出货
  11. 9号消费者准备出货:2个产品,当前仓库货物有:0个,【货物短缺,请尽快进货】,已经停止出货
  12. 8号消费者准备出货:9个产品,当前仓库货物有:0个,【货物短缺,请尽快进货】,已经停止出货
  13. 5号消费者准备出货:5个产品,当前仓库货物有:0个,【货物短缺,请尽快进货】,已经停止出货
  14. 7号消费者准备出货:5个产品,当前仓库货物有:0个,【货物短缺,请尽快进货】,已经停止出货
  15. 3号消费者准备出货:4个产品,当前仓库货物有:0个,【货物短缺,请尽快进货】,已经停止出货
  16. 2号消费者准备出货:3个产品,当前仓库货物有:0个,【货物短缺,请尽快进货】,已经停止出货
  17. 1号消费者准备出货:5个产品,当前仓库货物有:0个,【货物短缺,请尽快进货】,已经停止出货
  18. 当前仓库剩余货物数量,在最低警戒线一下,请抓紧时间补货!!!!!!!
  19. 10号生产者准备进货:1个产品,当前仓库货物有:0个,进货后仓库总有:1
  20. 当前仓库剩余货物数量,在最低警戒线一下,请抓紧时间补货!!!!!!!
  21. 9号生产者准备进货:3个产品,当前仓库货物有:1个,进货后仓库总有:4
  22. 当前仓库剩余货物数量,在最低警戒线一下,请抓紧时间补货!!!!!!!
  23. 8号生产者准备进货:5个产品,当前仓库货物有:4个,进货后仓库总有:9
  24. 当前仓库剩余货物数量,在最低警戒线一下,请抓紧时间补货!!!!!!!
  25. 8号生产者准备进货:5个产品,当前仓库货物有:9个,进货后仓库总有:14
  26. 当前仓库剩余货物数量,在最低警戒线一下,请抓紧时间补货!!!!!!!
  27. 7号生产者准备进货:9个产品,当前仓库货物有:14个,进货后仓库总有:23
  28. 6号生产者准备进货:9个产品,当前仓库货物有:23个,进货后仓库总有:32
  29. 5号生产者准备进货:1个产品,当前仓库货物有:32个,进货后仓库总有:33
  30. 4号生产者准备进货:8个产品,当前仓库货物有:33个,进货后仓库总有:41
  31. 3号生产者准备进货:9个产品,当前仓库货物有:41个,进货后仓库总有:50
  32. 2号生产者准备进货:8个产品,当前仓库货物有:50个,进货后仓库总有:58
  33. 3号生产者准备进货:9个产品,当前仓库货物有:58个,进货后仓库总有:67
  34. 4号生产者准备进货:8个产品,当前仓库货物有:67个,进货后仓库总有:75
  35. 5号生产者准备进货:1个产品,当前仓库货物有:75个,进货后仓库总有:76
  36. 6号生产者准备进货:9个产品,当前仓库货物有:76个,进货后仓库总有:85
  37. 6号生产者准备进货:9个产品,当前仓库货物有:85个,进货后仓库总有:94
  38. 6号生产者准备进货:9个产品,当前仓库货物有:94个,【货物超过仓库存放上限:100】,已经停止进货
  39. 7号生产者准备进货:9个产品,当前仓库货物有:94个,【货物超过仓库存放上限:100】,已经停止进货
  40. 8号生产者准备进货:5个产品,当前仓库货物有:94个,进货后仓库总有:99
  41. 9号生产者准备进货:3个产品,当前仓库货物有:99个,【货物超过仓库存放上限:100】,已经停止进货
  42. 10号生产者准备进货:1个产品,当前仓库货物有:99个,进货后仓库总有:100
  43. 2号消费者准备出货:3个产品,当前仓库货物有:100个,出货后仓库总有:97
  44. 2号消费者准备出货:3个产品,当前仓库货物有:97个,出货后仓库总有:94
  45. 3号消费者准备出货:4个产品,当前仓库货物有:94个,出货后仓库总有:90
  46. 3号消费者准备出货:4个产品,当前仓库货物有:90个,出货后仓库总有:86
  47. 3号消费者准备出货:4个产品,当前仓库货物有:86个,出货后仓库总有:82
  48. 3号消费者准备出货:4个产品,当前仓库货物有:82个,出货后仓库总有:78
  49. 5号消费者准备出货:5个产品,当前仓库货物有:78个,出货后仓库总有:73

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

多线程学习-基础(十二)生产者消费者模型:wait(),sleep(),notify()实现的更多相关文章

  1. python_way ,day11 线程,怎么写一个多线程?,队列,生产者消费者模型,线程锁,缓存(memcache,redis)

    python11 1.多线程原理 2.怎么写一个多线程? 3.队列 4.生产者消费者模型 5.线程锁 6.缓存 memcache redis 多线程原理 def f1(arg) print(arg) ...

  2. java多线程:线程间通信——生产者消费者模型

    一.背景 && 定义 多线程环境下,只要有并发问题,就要保证数据的安全性,一般指的是通过 synchronized 来进行同步. 另一个问题是,多个线程之间如何协作呢? 我们看一个仓库 ...

  3. Java多线程(九):生产者消费者模型

    生产者消费者模型 生产者:生产任务的个体: 消费者:消费任务的个体: 缓冲区:是生产者和消费者之间的媒介,对生产者和消费者解耦. 当 缓冲区元素为满,生产者无法生产,消费者继续消费: 缓冲区元素为空, ...

  4. Python多线程的简单实现(生产者消费者模型)

    __author__ = "JentZhang" import time, threading, queue q = queue.Queue(maxsize=) # 声明队列 de ...

  5. 学习了解 Exchanger - 实现生产者消费者模型

    例子很简单 Exchanger可以理解为消息队列或者说是一个通信管道,从一边拿到消息,另外一边进行消费. 不过这个是同步实现的,消费者在exchange之前,生产者一直处于等待状态,而不是一直生产. ...

  6. C++学习基础十二——纯虚函数与抽象类

    一.C++中纯虚函数与抽象类: 1.含有一个或多个纯虚函数的类成为抽象类,注意此处是纯虚函数,而不是虚函数. 2.如果一个子类继承抽象类,则必须实现父类中的纯虚函数,否则该类也为抽象类. 3.如果一个 ...

  7. Python3学习之路~9.4 队列、生产者消费者模型

    一 队列queue 当必须在多个线程之间安全地交换信息时,队列在线程编程中特别有用. 队列的作用:1.解耦,使程序直接实现松耦合 2.提高处理效率 列表与队列都是有顺序的,但是他们之间有一个很大的区别 ...

  8. Python多线程-生产者消费者模型

    用多线程和队列来实现生产者消费者模型 # -*- coding:utf-8 -*- __author__ = "MuT6 Sch01aR" import threading imp ...

  9. Day034--Python--锁, 信号量, 事件, 队列, 生产者消费者模型, joinableQueue

    进程同步: 1. 锁 (重点)    锁通常被用来实现对共享资源的同步访问.为每一个共享资源创建一个Lock对象,当你需要访问该资源时,调用acquire方法来获取锁对象(如果其它线程已经获得了该锁, ...

  10. python 并发编程 多进程 生产者消费者模型介绍

    一 生产者消费者模型介绍 为什么要使用生产者消费者模型 生产者指的是生产数据的任务,消费者指的是处理数据的任务, 生产数据目的,是为了给消费者处理. 在并发编程中,如果生产者处理速度很快,而消费者处理 ...

随机推荐

  1. HDFS超租约异常总结(org.apache.hadoop.hdfs.server.namenode.LeaseExpiredException)

    HDFS超租约异常总结(org.apache.hadoop.hdfs.server.namenode.LeaseExpiredException) 转载 2014年02月22日 14:40:58 96 ...

  2. LeetCode Shopping Offers

    原题链接在这里:https://leetcode.com/problems/shopping-offers/description/ 题目: In LeetCode Store, there are ...

  3. 2017.10.7北京清北综合强化班DAY7

    1.计数 (count.cpp/c/pas) 时间限制:1s 内存限制:256MB [问题描述] 给出m个数a[1],a[2],…,a[m] 求1~n中有多少数不是a[1],a[2],…,a[m]的倍 ...

  4. 加密第四节_IPSec基本理论

    加密第四节_IPSec基本理论 本节内容 IPSec简介 IPSec两种工作模式 判断隧道模式和传输模式 IPSec两种模型 IPSec两个数据库 IPSec基本理论 IPSec简介 提供了网络层的安 ...

  5. 洛谷【P1004】方格取数

    浅谈\(DP\):https://www.cnblogs.com/AKMer/p/10437525.html 题目传送门:https://www.luogu.org/problemnew/show/P ...

  6. python3小例子:scrapy+mysql

    https://blog.csdn.net/u010151698/article/details/79371234

  7. Azure VM复制

    目前Azure上复制VM可以有多种方法: 1 创建User Image,可以快速复制多台VM,但目前托管磁盘只支持Generalized的模式,需要对User和配置进行重置. 2 从VHD或托管磁盘复 ...

  8. kubernetes 学习 创建cronjob

    POM.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...

  9. Centos 7.2 编译安装 git

    一. 下载最新版GIT安装包: https://www.kernel.org/pub/software/scm/git/ 选择想要安装的版本,下载,解压 命令: .tar.gz $ cd git- 二 ...

  10. ansible for devops 读书笔记第二章Ad-Hoc Commands

    参数 参数 说明 -a ‘Arguments’, —args=’Arguments’ 命令行参数 -m NAME, —module-name=NAME 执行模块的名字,默认使用 command 模块, ...