经典消费者生产者问题
来源:互联网 发布:网络购票如何买下铺 编辑:程序博客网 时间:2024/06/03 20:19
首先你需要了解多线程的流程以及实现多线程的几种方法,同时你要理解什么是并行、并发,以及线程和进程的区别,这里做简要的区别。
线程:一个进程包括多个线程
并行:多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时。
并发:通过cpu调度算法,让用户看上去同时执行,实际上从cpu操作层面不是真正的同时。并发往往在场景中有公用的资源,那么针对这个公用的资源往往产生瓶颈,我们会用TPS或者QPS来反应这个系统的处理能力。
之前看到过一篇博客,我觉得很形象的解释了并行和并发,下面我借用他的一个图片解释一下
就如同喝咖啡一样,并行是让一杯咖啡被两种人同时喝,而并发是有可能有两杯咖啡,两种人同时喝,看起来是同时进行,但不是真正的同时。
多线程的基本流程
新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();
就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;
运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就 绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;
阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:
1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
2.同步阻塞 – 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;
3.其他阻塞 – 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
好了下面进入我们的生产者消费者问题
生产者消费者问题
考虑一个程序的怎么写首先应该有大概的流程,生产消费问题其实也就是生产——仓库——消费 模型
1.首先应该建立仓库类、消费者类、生产者类、以及最终的测试类。
2.我们应该判断的是如果消费者消耗光仓库的食物,我们应该让消费者们等待,然后notifyAll所有的生产者,直到生产者生产的食物等于仓库容量,我们可以停止生产,进入wait状态,然后唤醒所有消费者消费食物。大体的思路就是这样。
下面用真正的代码实现
仓库类
package com.cn.hnust.controller;import sun.org.mozilla.javascript.internal.Synchronizer;import java.util.LinkedList;public class CangKu { private final int MAX_SIZE=100; //仓库最大容量 LinkedList<Object> linkedList= new LinkedList();//载体 public LinkedList<Object> getLinkedList() { return linkedList; } public void setLinkedList(LinkedList<Object> linkedList) { this.linkedList = linkedList; } /** * 生产者方法 * @param num */ public void produce(int num ){ synchronized (linkedList){ while(linkedList.size()+num>MAX_SIZE){ System.out.println("不能生产,食物够用"+num+"size==="+linkedList.size()); try { linkedList.wait(); }catch (Exception e){ e.printStackTrace(); } } for (int i=1;i<=num;++i){ linkedList.add(new Object()); } System.out.println("已经生产" +num+ "总共有"+linkedList.size()); linkedList.notifyAll(); } } public int getMAX_SIZE() { return MAX_SIZE; } /** * 消费者方法 * @param num */ public void consoume(int num ){ synchronized (linkedList){ while(linkedList.size()<num){ try { System.out.println("消费"+num +"size"+linkedList.size()); linkedList.wait(); }catch (Exception e){ e.printStackTrace(); } } for (int i=1;i<=num;++i){ linkedList.remove(); } System.out.println("【已经消费产品数】:" + num + "/t【现仓储量为】:" + linkedList.size()); linkedList.notifyAll(); } }}
生产类
package com.cn.hnust.controller;public class proudcter extends Thread {private int num; public int getNum() { return num; } public void setNum(int num) { this.num = num; } public CangKu getCangKu() { return cangKu; } public void setCangKu(CangKu cangKu) { this.cangKu = cangKu; } private CangKu cangKu;public proudcter(CangKu cangKu){ this.cangKu=cangKu;} public void proudce(int num) { cangKu.produce(num); } public void run(){ proudce(num);}}
消费者类
package com.cn.hnust.controller;public class consumers extends Thread { private int num; public int getNum() { return num; } public void setNum(int num) { this.num = num; } public CangKu getCangKu() { return cangKu; } public void setCangKu(CangKu cangKu) { this.cangKu = cangKu; } private CangKu cangKu; public consumers(CangKu cangKu1){ this.cangKu=cangKu1; } public void consum(int num) { cangKu.consoume(num); } public void run(){ consum(num); }}
主类
package com.cn.hnust.controller;public class PCTest { public static void main(String[] args) { CangKu cangKu =new CangKu(); proudcter proudcter =new proudcter(cangKu); proudcter proudcter1 =new proudcter(cangKu); proudcter proudcter2 =new proudcter(cangKu); proudcter proudcter3 =new proudcter(cangKu); proudcter proudcter4 =new proudcter(cangKu); proudcter proudcter5 =new proudcter(cangKu); consumers consumers =new consumers(cangKu); consumers consumers1 =new consumers(cangKu); consumers consumers2 =new consumers(cangKu); consumers consumers3 =new consumers(cangKu); proudcter.setNum(10); proudcter1.setNum(10); proudcter2.setNum(10); proudcter3.setNum(90); proudcter4.setNum(10); proudcter5.setNum(80); consumers.setNum(50); consumers1.setNum(20); consumers2.setNum(60); consumers3.setNum(10); consumers.start(); consumers1.start(); consumers2.start(); consumers3.start(); proudcter.start(); proudcter1.start(); proudcter2.start(); proudcter3.start(); proudcter4.start(); proudcter5.start(); }}
以上就是生产者消费者问题,如果有不对之处,希望指出。共同进步,谢谢。
- 经典生产者消费者问题
- 【经典问题】生产者消费者
- 经典消费者生产者问题
- 经典问题-生产者和消费者
- java生产者消费者经典问题
- 经典问题-生产者和消费者问题
- 经典进程同步问题-生产者消费者问题
- 经典进程同步问题-生产者与消费者
- 经典进程问题:生产者与消费者
- 经典线程同步问题(生产者&消费者)
- 多线程八 生产者消费者经典问题
- java多线程之生产者消费者经典问题
- 经典多线程实例:生产者消费者问题
- 线程经典,生产者与消费者问题
- 多线程经典问题-生产者与消费者
- 多线程之经典生产者消费者问题
- java同步经典问题生产者消费者
- java多线程之生产者消费者经典问题
- Python 正则表达式 匹配邮箱地址
- 原生JS、CSS3 上拉刷新效果的实现。
- 【tf系列2】参数说明
- 模块获取工具
- 正则表达式分组捕获说明
- 经典消费者生产者问题
- ArcGIS API for Javascript3.23加载高德地图
- 解决同一个页面不能跳转的问题
- Include and Exclude Test Methods in TestNG
- 《懒人Shell脚本》之十——统计多重路径下的不同扩展名文件及个数
- os模块有关
- 阿里云总裁胡晓明:AI泡沫过后,下一站是“产业AI”
- Recycleview添加item点击事件
- Unity3D