【java并发系列】java多线程实现生产者消费者模式
大家好,我是walker
一个从文科自学转行的程序员~
爱好编程,偶尔写写编程文章和生活
欢迎关注公众号【I am Walker】,回复“电子书”,就可以获得200多本编程相关电子书哈~
我的gitee:https://gitee.com/shen-chuhao/walker.git 里面很多技术案例!
简介
一般来说,生产者和消费者模式可以实现对任务数量的控制,防止任务过多,导致程序处理不来。
主要思想
- 当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界资源(即队列)的占用权。因为生产者如果不释放对临界资源的占用权,那么消费者就无法消费队列中的商品,就不会让队列有空间,那么生产者就会一直无限等待下去。
- 因此,一般情况下,当队列满时,会让生产者交出对临界资源的占用权,并进入挂起状态。然后等待消费者消费了商品,然后消费者通知生产者队列有空间了。
- 同样地,当队列空时,消费者也必须等待,等待生产者通知它队列中有商品了。这种互相通信的过程就是线程间的协作。
总结:
- 队列满,生产者等待,消费者消费
- 队列空,消费者等待,生产者生产
案例
假设有生产者可以生产包子,消费者消费包子,这里是实现方式是使用阻塞队列BlockingQueue实现的
1、定义生产者
package productConsumerMode.blockingQueue;import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;/*** 生产者*/
public class Producer implements Runnable {//该字段用于做是否循环的字段 这里使用volatile保证可见性和防止指令重排private volatile boolean isRunning = true;//线程休眠时间,防止线程调用速度太快private final static int SLEEP_TIME = 1000;//包子阻塞队列,用来存储生产的包子private BlockingQueue<String> bumQueue;//包子序号private static AtomicInteger serial = new AtomicInteger();/*** 构造方法* 参数为:包子队列*/public Producer(BlockingQueue<String> bumQueue) {this.bumQueue = bumQueue;}/*** 重写run方法*/@Overridepublic void run() {//当isRunning=true的时候,循环进行生产while (isRunning) {try {/*** boolean offer(E e, long timeout, TimeUnit unit) 若2秒还没有加入,则代表队列阻塞,这时候打印加入队列失败,否则则加入队列*/if (!bumQueue.offer("包子" + serial.getAndAdd(1), 2, TimeUnit.SECONDS)) {System.out.println("队列的数量为:" + bumQueue.size() + ",无法加入队列");} else {System.out.println("【生产者】" + Thread.currentThread().getName() + "生产包子" + serial.get());}//线程休眠Thread.sleep(SLEEP_TIME);} catch (InterruptedException e) {e.printStackTrace();}}}public void stopProduct() {isRunning = false;}
}
2、定义消费者
package productConsumerMode.blockingQueue;import java.util.concurrent.BlockingQueue;/*** 消费者*/
public class Consumer implements Runnable {//包子队列private BlockingQueue<String> bumQueue;//是否支持消费private volatile boolean isConsumer=true;//构造方法public Consumer(BlockingQueue<String> bumQueue) {this.bumQueue = bumQueue;}@Overridepublic void run() {while(isConsumer){//从队列中获取包子String bum = bumQueue.poll();//若包子存在,则消费 若不存在则提示没有包子消费if (bum != null) {System.out.println("【消费者】" + Thread.currentThread().getName() + "消费" + bum);}else{System.out.println("包子数量剩余"+bumQueue.size()+",没有包子可以消费");}//此处让线程休眠一下,防止消费太快try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}}public void stopConsumer(){isConsumer=false;}
}
3、测试
package productConsumerMode.blockingQueue;import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;/*** @Author: WalkerShen* @DATE: 2022/3/16* @Description: 使用blockingQueue实现生产者消费者模式* 案例:生产者生产包子 消费者买包子**/
public class BlockingQueueTest {public static void main(String[] args) throws InterruptedException {//创建一个阻塞队列,容量为10BlockingQueue<String> bumQueue=new LinkedBlockingQueue<>(10);//创建RunnableProducer producer1 = new Producer(bumQueue);Producer producer2 = new Producer(bumQueue);Consumer consumer1 = new Consumer(bumQueue);Consumer consumer2 = new Consumer(bumQueue);//使用Executors工具执行线程ExecutorService executorService = Executors.newCachedThreadPool();executorService.execute(consumer1);executorService.execute(consumer2);executorService.execute(producer1);executorService.execute(producer2);//让主线程休眠20秒,这里是为了查看执行的结果Thread.sleep(20*1000);//停止生产和消费producer1.stopProduct();producer2.stopProduct();consumer1.stopConsumer();consumer2.stopConsumer();//最后关闭线程池executorService.shutdown();}}
【java并发系列】java多线程实现生产者消费者模式相关推荐
- Java(二十二) -- 生产者消费者模式
目录 生产者消费者模式 汉堡类 容器类 生产者 消费者 测试类 案例:多线程并发卖票 生产者消费者模式 在一个生产环境中,生产者和消费者在同一时间段内共享同一块缓冲区,生产者负责向缓冲区添加数据,消费 ...
- 并发编程(五)——生产者消费者模式
2019独角兽企业重金招聘Python工程师标准>>> 在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据 ...
- 【多线程】--生产者消费者模式--synchronized版本
在实现生产者消费者模式之前,我们先了解一下线程的5种状态:被创建.运行.冻结.消亡.阻塞,如下图: 在Jdk1.5发布之前,我们实现生产者消费者模式一般使用synchronized + while循环 ...
- Python多线程实现生产者消费者模式
什么是生产者消费者模式 在软件开发的过程中,经常碰到这样的场景: 某些模块负责生产数据,这些数据由其他模块来负责处理(此处的模块可能是:函数.线程.进程等).产生数据的模块称为生产者,而处理数据的模块 ...
- java中synchronized同步锁实现生产者消费者模式
synchronized介绍 一.基本概念 synchronized关键字是java里面用来在多线程环境下保证线程安全的同步锁:java里面有对象锁和类锁,对象锁是用在对象实例的方法上或者一个对象实例 ...
- C++多线程实现生产者消费者模式
这里记录C++多线程实现生成者消费者模式. 代码执行环境:wins Visual Studio 2017 执行逻辑:生产者和消费者公用一个队列作为临界资源,当队列满时生产者暂停生成:当队列为空时,消费 ...
- java consumed_Java设计模式—生产者消费者模式(阻塞队列实现)
生产者消费者模式是并发.多线程编程中经典的 真实世界中的生产者消费者模式 生产者和消费者模式在生活当中随处可见,它描述的是协调与协作的关系.比如一个人正在准备食物(生产者),而另一个人正在吃(消费者) ...
- java 读者写者_Java实现生产者消费者问题与读者写者问题详解
1.生产者消费者问题 生产者消费者问题是研究多线程程序时绕不开的经典问题之一,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品.解决生产者/消费者问题的方法可分为两 ...
- 并发编程(五)python实现生产者消费者模式多线程爬虫
并发编程专栏系列博客 并发编程(一)python并发编程简介 并发编程(二)怎样选择多线程多进程和多协程 并发编程(三)Python编程慢的罪魁祸首.全局解释器锁GIL 并发编程(四)如何使用多线程, ...
最新文章
- 起售价近5500,嘲讽了iPhone X的华为Mate 10却没用上人脸识别
- 深度学习--说一说卷积和池化
- 同在服务器无响应,全部服务器无响应!!!
- 硅谷最有名的帮派:如果你不知道PayPal黑帮
- 30 | 套路篇:如何迅速分析出系统I/O的瓶颈在哪里?
- gVim 中文内容显示为乱码的解决办法
- Java黑皮书课后题第5章:*5.1(统计正数和负数的个数然后计算这些数的平均值)编写程序,读入未指定个数的整数,判断读入的正数有多少个、负数有多少个,然后计算输入值的总和和平均值(不记0,浮点表示)
- golang中的defer
- dubbo优势_Dubbo 迈出云原生重要一步 应用级服务发现解析
- 通过反射获取方法返回的类型
- 又栽了?苹果侵犯高通三项专利需赔偿3100万美元
- mysql用户增删改
- java字符串数字统计_对字符串进行简单的字符数字统计 探索java中的List功能
- QGIS 3.0 使用教程
- python处理页眉_python批量替换页眉页脚实例代码
- Java爬取彼岸桌面壁纸的实现(使用Jsoup)
- 【转】计算机分类经典书籍推荐
- 计算机的文件结构图,如何科学的整理电脑文件?
- 外汇天眼:英国研究人员与南非合作应对气候变化
- 数据结构分析之线性哈希表(Linear Hash Tables)