【1】生产者-消费者模型的三种实现方式
(手写生产者消费者模型,写BlockingQueue较简便 )
1、背景
生产者生产数据到缓冲区中,消费者从缓冲区中取数据。
如果缓冲区已经满了,则生产者线程阻塞;
如果缓冲区为空,那么消费者线程阻塞。
2、方式一:synchronized、wait和notify
add()和remove()方法是synchronized 的
package producerConsumer; //wait 和 notify public class ProducerConsumerWithWaitNofity {public static void main(String[] args) {Resource resource = new Resource();//生产者线程ProducerThread p1 = new ProducerThread(resource);ProducerThread p2 = new ProducerThread(resource);ProducerThread p3 = new ProducerThread(resource);//消费者线程ConsumerThread c1 = new ConsumerThread(resource);//ConsumerThread c2 = new ConsumerThread(resource);//ConsumerThread c3 = new ConsumerThread(resource); p1.start();p2.start();p3.start();c1.start();//c2.start();//c3.start(); }} /*** 公共资源类* @author **/ class Resource{//重要//当前资源数量private int num = 0;//资源池中允许存放的资源数目private int size = 10;/*** 从资源池中取走资源*/public synchronized void remove(){if(num > 0){num--;System.out.println("消费者" + Thread.currentThread().getName() +"消耗一件资源," + "当前线程池有" + num + "个");notifyAll();//通知生产者生产资源}else{try {//如果没有资源,则消费者进入等待状态 wait();System.out.println("消费者" + Thread.currentThread().getName() + "线程进入等待状态");} catch (InterruptedException e) {e.printStackTrace();}}}/*** 向资源池中添加资源*/public synchronized void add(){if(num < size){num++;System.out.println(Thread.currentThread().getName() + "生产一件资源,当前资源池有" + num + "个");//通知等待的消费者 notifyAll();}else{//如果当前资源池中有10件资源try{wait();//生产者进入等待状态,并释放锁System.out.println(Thread.currentThread().getName()+"线程进入等待");}catch(InterruptedException e){e.printStackTrace();}}} } /*** 消费者线程*/ class ConsumerThread extends Thread{private Resource resource;public ConsumerThread(Resource resource){this.resource = resource;}@Overridepublic void run() {while(true){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}resource.remove();}} } /*** 生产者线程*/ class ProducerThread extends Thread{private Resource resource;public ProducerThread(Resource resource){this.resource = resource;}@Overridepublic void run() {//不断地生产资源while(true){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}resource.add();}}}
View Code
3、方式二:lock和condition的await、signalAll
package producerConsumer;import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /*** 使用Lock 和 Condition解决生产者消费者问题* @author tangzhijing**/ public class LockCondition {public static void main(String[] args) {Lock lock = new ReentrantLock();Condition producerCondition = lock.newCondition();Condition consumerCondition = lock.newCondition();Resource2 resource = new Resource2(lock,producerCondition,consumerCondition);//生产者线程ProducerThread2 producer1 = new ProducerThread2(resource);//消费者线程ConsumerThread2 consumer1 = new ConsumerThread2(resource);ConsumerThread2 consumer2 = new ConsumerThread2(resource);ConsumerThread2 consumer3 = new ConsumerThread2(resource);producer1.start();consumer1.start();consumer2.start();consumer3.start();} } /*** 消费者线程*/ class ConsumerThread2 extends Thread{private Resource2 resource;public ConsumerThread2(Resource2 resource){this.resource = resource;//setName("消费者"); }public void run(){while(true){try {Thread.sleep((long) (1000 * Math.random()));} catch (InterruptedException e) {e.printStackTrace();}resource.remove();}} } /*** 生产者线程* @author tangzhijing**/ class ProducerThread2 extends Thread{private Resource2 resource;public ProducerThread2(Resource2 resource){this.resource = resource;setName("生产者");}public void run(){while(true){try {Thread.sleep((long) (1000 * Math.random()));} catch (InterruptedException e) {e.printStackTrace();}resource.add();}} } /*** 公共资源类* @author tangzhijing**/ class Resource2{private int num = 0;//当前资源数量private int size = 10;//资源池中允许存放的资源数目private Lock lock;private Condition producerCondition;private Condition consumerCondition;public Resource2(Lock lock, Condition producerCondition, Condition consumerCondition) {this.lock = lock;this.producerCondition = producerCondition;this.consumerCondition = consumerCondition;}/*** 向资源池中添加资源*/public void add(){lock.lock();try{if(num < size){num++;System.out.println(Thread.currentThread().getName() + "生产一件资源,当前资源池有" + num + "个");//唤醒等待的消费者 consumerCondition.signalAll();}else{//让生产者线程等待try {producerCondition.await();System.out.println(Thread.currentThread().getName() + "线程进入等待");} catch (InterruptedException e) {e.printStackTrace();}}}finally{lock.unlock();}}/*** 从资源池中取走资源*/public void remove(){lock.lock();try{if(num > 0){num--;System.out.println("消费者" + Thread.currentThread().getName() + "消耗一件资源," + "当前资源池有" + num + "个");producerCondition.signalAll();//唤醒等待的生产者}else{try {consumerCondition.await();System.out.println(Thread.currentThread().getName() + "线程进入等待");} catch (InterruptedException e) {e.printStackTrace();}//让消费者等待 }}finally{lock.unlock();}}}
View Code
4、方式三:BlockingQueue
package producerConsumer;import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue;//使用阻塞队列BlockingQueue解决生产者消费者 public class BlockingQueueConsumerProducer {public static void main(String[] args) {Resource3 resource = new Resource3();//生产者线程ProducerThread3 p = new ProducerThread3(resource);//多个消费者ConsumerThread3 c1 = new ConsumerThread3(resource);ConsumerThread3 c2 = new ConsumerThread3(resource);ConsumerThread3 c3 = new ConsumerThread3(resource);p.start();c1.start();c2.start();c3.start();} } /*** 消费者线程* @author tangzhijing**/ class ConsumerThread3 extends Thread {private Resource3 resource3;public ConsumerThread3(Resource3 resource) {this.resource3 = resource;//setName("消费者"); }public void run() {while (true) {try {Thread.sleep((long) (1000 * Math.random()));} catch (InterruptedException e) {e.printStackTrace();}resource3.remove();}} } /*** 生产者线程* @author tangzhijing**/ class ProducerThread3 extends Thread{private Resource3 resource3;public ProducerThread3(Resource3 resource) {this.resource3 = resource;//setName("生产者"); }public void run() {while (true) {try {Thread.sleep((long) (1000 * Math.random()));} catch (InterruptedException e) {e.printStackTrace();}resource3.add();}} } class Resource3{private BlockingQueue<Integer> resourceQueue = new LinkedBlockingQueue<>(10);/*** 向资源池中添加资源*/public void add(){try {resourceQueue.put(1); //1当做生产和消费的Integer资源System.out.println("生产者" + Thread.currentThread().getName()+ "生产一件资源," + "当前资源池有" + resourceQueue.size() + "个资源");} catch (InterruptedException e) {e.printStackTrace();}}/*** 向资源池中移除资源*/public void remove(){try {resourceQueue.take();System.out.println("消费者" + Thread.currentThread().getName() + "消耗一件资源," + "当前资源池有" + resourceQueue.size() + "个资源");} catch (InterruptedException e) {e.printStackTrace();}} }
View Code
转载于:https://www.cnblogs.com/twoheads/p/10137263.html
【1】生产者-消费者模型的三种实现方式相关推荐
- 生产者消费者模型的三种实现方式
某个线程或模块的代码负责生产数据(工厂),而生产出来的数据却不得不交给另一模块(消费者)来对其进行处理,在这之间使用了队列.栈等类似超市的东西来存储数据(超市),这就抽象除了我们的生产者/消费者模型. ...
- 生产者-消费者模式的三种实现方式
2.生产者-消费者模式的三种实现方式 1.背景 生产者生产数据到缓 ...
- java生产者消费者流程图_Java 生产者消费者模型的三种实现过程
生产者一边在生产,消费者一边消耗.当库存满的时候生产者暂停生产,直到有空位:当库存空的时候消费者暂停消费,直到有产品. 关键点: 生产者和消费者都是在不断生产和消费的,是同时并发的,不应该等满了再消费 ...
- 生产者-消费者模型的两种实现方式
https://www.cnblogs.com/caolicangzhu/p/7086176.html 本文主要来总结生产者-消费者模型的代码实现,至于其原理,请大家自行百度. 一.基于链表的生产-消 ...
- 生产者消费者模式的三种实现方式
原作者:老铁123 出处:https://blog.csdn.net/qewgd/article/details/85926275 本文归作者[老铁123]和博客园共有,欢迎转载,但未经作者同意必须保 ...
- 【Java】生产者消费者模式的三种实现
原文地址:https://blog.csdn.net/u010983881/article/details/78554671 前言 生产者消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内 ...
- 操作系统:生产者消费者模型的两种实现(C++)
文章目录 生产者消费者模型 什么是生产者消费者模型 生产者消费者模型的321原则 生产者消费者模型的优点 生产者消费者模型的实现方法 基于循环队列,信号量实现 基于阻塞队列,互斥锁.条件变量实现 生产 ...
- Java生产者 消费者模型的一种实现
本文主要介绍java中生产者/消费者模式的实现,对java线程锁机制的一次深入理解. 生产者/消费者模型 生产者/消费者模型要保证,同一个资源在同一时间节点下只能被最多一个线程访问,这个在java中用 ...
- 生产者消费者问题Java三种实现
生产者-消费者Java实现 2017-07-27 1 概述 生产者消费者问题是多线程的一个经典问题,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品. 解决生产者/ ...
最新文章
- python基础-第九篇-9.3线程池
- python 3.7.732位安装步骤_python安装教程(Windows系统,python3.7为例)
- 2的1000 次是超出python表示范围的整数。_第4卷讲解Python语言计算机等级考试二级操作题...
- 用神经网络分类随机数与无理数
- Topk 问题详解及代码和数据分析
- node简介及安装、下载及运行hexo
- python爬去百度百科词条_Python爬虫入门学习实践——爬取小说
- cefSharp 开发随笔
- python 下载csv文件保存到 redis
- Tensorflow(r1.4)API--tf.truncated_normal()
- 23. 变量、作用域和内存问题
- apache 添加虚拟机
- 第一部分 第二章 答案合集(part 2)1024-1038
- 图灵奖Alan Kay:突破常规思维!道翰天琼认知智能机器人平台API接口大脑为您揭秘
- 在追梦的路上,唯独脚踏实地,才能梦想成真
- HDU 6617 Enveloping Convex(凸包+半平面交+二分)
- 集线器、交换机以及路由器异同 + 冲突域和广播域详解
- android SAF存储访问框架
- 【MPLS】LDP保留的标签
- CentOS wc命令详解
热门文章
- 【Linux】FTP文件下载
- Linux下获得线程ID syscall(224)
- [Redux/Mobx] 你有使用过redux-saga中间件吗?它是干什么的?
- javascript学习系列(8):数组中的splice方法
- 前端学习(3135):react-hello-react之函数的柯里化
- 前端学习(3014):vue+element今日头条管理--自定义验证
- [css] 对比下px、em、rem有什么不同?
- [css] 说说你对GPU的理解,举例说明哪些元素能触发GPU硬件加速?
- 工作213:不能改变父组件值
- 前端学习(2239):小滴后台管理系统简介