【多线程案例】生产者消费者模型(堵塞队列)
文章目录
- 1. 什么是堵塞队列?
- 2. 堵塞队列的方法
- 3. 生产者消费者模型
- 4. 自己实现堵塞队列
1. 什么是堵塞队列?
堵塞队列也是队列,故遵循先进先出的原则。但堵塞队列是一种线程安全的数据结构,可以避免线程安全问题,当队列为空时,继续出队列会发生堵塞,直至其他线程有元素进队列。当队列满时,继续入队列会堵塞,直至其他线程有元素出队列。
生产者消费者模型就是最经典的堵塞队列模型之一。
2. 堵塞队列的方法
Java标准库里含有堵塞队列,我们使用时可以直接使用标准库即可。
- BlockingQueue是个接口,真正实现的类是:LinkedBlockingQueue。
- put方法入队列,take方法出队列,具有堵塞性。
- peek,offer,poll等方法也可以使用,但是不具有堵塞性。
BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
queue.put();
queue.take();
3. 生产者消费者模型
这是一个常见的并发编程模型,用于协调生产者和消费者之间的工作,在这个模型中,一个线程负责生产元素,一个线程负责消费元素。
它也是一个堵塞队列 ,所以具有堵塞队列的特性。
public class Test {public static void main(String[] args) {BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();//t1线程负责生产元素Thread t1 = new Thread(() -> {try{Random random = new Random();while (true){int i = random.nextInt();System.out.println("生产元素: " + i);queue.put(i);Thread.sleep(1000);}}catch (InterruptedException e){e.printStackTrace();}});//t2负责消费元素Thread t2 = new Thread(() -> {try {while(true){int i = queue.take();System.out.println("消费元素: " + i);}} catch (InterruptedException e) {e.printStackTrace();}});t1.start();t2.start();}
}
运行结果:
4. 自己实现堵塞队列
自己实现堵塞队列需要满足:
- 通过循环队列来实现;
- 使用synchronized实现加锁,进行同步;
- put 插入元素的时候, 判定如果队列满了, 就进行 wait. (注意, 要在循环中进行 wait. 被唤醒时不一定队列就不满了, 因为同时可能是唤醒了多个线程);
- take 取出元素的时候, 判定如果队列为空, 就进行 wait. (也是循环 wait) ;
class BlockingQueue{//定义一个数组private int[] arr;//数组中元素个数private int size = 0;//记录数组头的位置private int read = 0;//记录尾的位置private int tail = 0;//锁Object lock = new Object();//构造方法,确定数组大小public BlockingQueue(int i){arr = new int[i];}//入队列public void put(int value){try{//加锁,保证线程安全synchronized (lock){//使用while,不要使用if,否则notifyAll时,所有等待线程都被唤醒,造成线程安全while(arr.length == size){lock.wait();}arr[tail] = value;//循环队列tail = (tail + 1) % arr.length;//添加一个元素,size加一次size++;//唤醒所有线程lock.notifyAll();}}catch (InterruptedException e){e.printStackTrace();}}public int take() {//返回值,不能写在try里面int value = 0;try {//上锁synchronized (lock) {//队列为0,等待,使用whilewhile (size == 0) {lock.wait();}//赋返回值value = arr[read];//循环read = (read + 1) % arr.length;//出队列一个,减一个size--;//唤醒lock.notifyAll();}} catch (InterruptedException e) {e.printStackTrace();}//返回值return value;}}
public class Test4 {public static void main(String[] args) throws InterruptedException {BlockingQueue queue = new BlockingQueue(10);Thread t1 = new Thread(() -> {try{Random random = new Random();while (true){int value = random.nextInt(100);System.out.println("生产元素: " + value);queue.put(value);Thread.sleep(100);}}catch (InterruptedException e){e.printStackTrace();}});//t2负责消费元素Thread t2 = new Thread(() -> {while(true){int value = queue.take();System.out.println("消费元素: " + value);}});t1.start();Thread.sleep(2000);t2.start();}
}
1 因为t2 未启动,所以只能生产元素,当生产10个元素后,队列满了,进入堵塞,等待被唤醒;
2 因为t1生产时,每次都会休眠,线程执行非常迅速,所以队列一直出元素,直到队列为空,进入堵塞,等待被唤醒;
3生产一个元素消费一个元素。
相关文章:

【多线程案例】生产者消费者模型(堵塞队列)
文章目录 1. 什么是堵塞队列?2. 堵塞队列的方法3. 生产者消费者模型4. 自己实现堵塞队列 1. 什么是堵塞队列? 堵塞队列也是队列,故遵循先进先出的原则。但堵塞队列是一种线程安全的数据结构,可以避免线程安全问题,当队…...

数据结构与算法基础-学习-30-插入排序之直接插入排序、二分插入排序、希尔排序
一、排序概念 将一组杂乱无章的数据按一定规律顺次排列起来。 将无序序列排成一个有序序列(由小到大或由大到小)的运算。 二、排序方法分类 1、按数据存储介质 名称描述内部排序数据量不大、数据在内存,无需内外交换存交换存储。外部排序…...

Qt+C++桌面计算器源码
程序示例精选 QtC桌面计算器源码 如需安装运行环境或远程调试,见文章底部个人QQ名片,由专业技术人员远程协助! 前言 这篇博客针对<<QtC桌面计算器源码>>编写代码,代码整洁,规则,易读。 学习与…...

kubesphere安装Maven+JDK17 流水线打包
kubesphere 3.4.0版本,默认支持的jav版本是8和11,不支持17 。需要我们自己定义JenKins Agent 。方法如下: 一、构建镜像 1、我们需要从Jenkins Agent的github仓库拉取master最新源码,最新源码里已经支持jdk17了。 git clone ht…...

百度搜索清理大量低质量网站
我是卢松松,点点上面的头像,欢迎关注我哦! 据部分站长爆料:百度大规模删低质量网站的百度资源站长平台权限,很多网站都被删除了百度站长资源平台后台权限,以前在百度后台添加的网站大量被删除!…...
WPF数据模板
样式提供了基本的格式化能力,但它们不能消除到目前为止看到的列表的最重要的局限性:不管如何修改ListBoxItem,它都只是ListBoxItem,而不是功能更强大的元素组合。并且因为每个ListBoxItem只支持单个绑定字段,所以不可能…...

浙江绿农环境:将废弃矿山变耕地,为生态文明贡献力量
近年来,随着可持续发展理念在中国乃至全球的日益普及,浙江绿农生态环境有限公司以其独特的创新和实践,成为了绿色发展的典范,在奋进新时代、建设新天堂的背景下,绿农环境在杭州市固废治理行业迈出坚实的步伐࿰…...
HTML/CSS盒子模型
盒子:页面中的所有的元素(标签),都可以看做一个盒子,由盒子将页面中的元素包含在一个矩形区域内,通过盒子的视角更加方便的进行页面布局 盒子模型的组成: 内容区域(contentÿ…...
《Java面向对象程序设计》学习笔记——CSV文件的读写与处理
笔记汇总:《Java面向对象程序设计》学习笔记 笔记记录的不是非常详实,如果有补充的建议或纠错,请踊跃评论留言!!! 什么是CSV文件 CSV文件的定义 CSV 是英文 comma-separated values 的缩写࿰…...

opencv 案例05-基于二值图像分析(简单缺陷检测)
缺陷检测,分为两个部分,一个部分是提取指定的轮廓,第二个部分通过对比实现划痕检测与缺角检测。本次主要搞定第一部分,学会观察图像与提取图像ROI对象轮廓外接矩形与轮廓。 下面是基于二值图像分析的大致流程 读取图像将图像转换…...
Elasticsearch入门介绍
应用场景 1 它提供了强大的搜索功能,可以实现类似百度、谷歌等搜索。 2 可以搜索日志或者交易数据,用来分析商业趋势、搜集日志、分析系统瓶颈或者运行发展等等 3 可以提供预警功能(持续的查询分析某个数据,如果超过一定的值&a…...

QML Book 学习基础3(动画)
目录 主要动画元素 例子: 非线性动画 分组动画 Qt 动画是一种在 Qt 框架下创建交互式和引人入胜的图形用户界面的方法,我们可以认为是对某个基础元素的多个设置 主要动画元素 PropertyAnimation-属性值变化时的动画 NumberA…...

Lesson4-3:OpenCV图像特征提取与描述---SIFT/SURF算法
学习目标 理解 S I F T / S U R F SIFT/SURF SIFT/SURF算法的原理,能够使用 S I F T / S U R F SIFT/SURF SIFT/SURF进行关键点的检测 SIFT/SURF算法 1.1 SIFT原理 前面两节我们介绍了 H a r r i s Harris Harris和 S h i − T o m a s i Shi-Tomasi Shi−Tomasi…...
语言基础篇9——Python流程控制
流程控制 顺序结构、条件结构、循环结构,顺序结构由自上而下的语句构成,条件结构由if、match-case构成,循环结构由for、while构成。 if语句 flag 1 if flag 1:print("A") elif flag 2:print("B") else:print("…...
MATLAB算法实战应用案例精讲-【概念篇】构建数据指标方法(补充篇)
目录 前言 几个高频面试题目 指标与标签的区别 几个相关概念 数据域 业务过程...

【pyqt5界面化工具开发-12】QtDesigner图形化界面设计
目录 0x00 前言 一、启动程序 二、基础的使用 三、保存布局文件 四、加载UI文件 0x00 前言 关于QtDesigner工具的配置等步骤(网上链接也比较多) 下列链接非本人的(如果使用pip 在命令行安装过pyqt5以及tools,那么就可以跳过…...

CXL.mem S2M Message 释义
🔥点击查看精选 CXL 系列文章🔥 🔥点击进入【芯片设计验证】社区,查看更多精彩内容🔥 📢 声明: 🥭 作者主页:【MangoPapa的CSDN主页】。⚠️ 本文首发于CSDN,…...

设计模式—外观模式(Facade)
目录 一、什么是外观模式? 二、外观模式具有什么优点吗? 三、外观模式具有什么缺点呢? 四、什么时候使用外观模式? 五、代码展示 ①、股民炒股代码 ②、投资基金代码 ③外观模式 思维导图 一、什么是外观模式?…...
Stack Overflow开发者调查发布:AI将如何协助DevOps
Stack Overflow 发布了开创性的2023年度开发人员调查报告 [1]。报告对 90,000 多名开发人员进行了调查,全面展示了当前软件开发人员的体验。接下来,本文将重点介绍几项重要发现,即重要编程语言和工具偏好、人工智能在开发工作流程中的应用以及…...
去掉鼠标系列之二:Sublime Text快捷键使用指南
系列之二,Sublime Text。 Sublime Text 是我们常用的文本工具,常常要沉浸如其中使用,而不希望被鼠标打扰,所以也记录一下。 学会下面这些快捷键,基本上就不需要移动鼠标啦。 1,CtrlK,CtrlV …...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!
目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...
Java并发编程实战 Day 11:并发设计模式
【Java并发编程实战 Day 11】并发设计模式 开篇 这是"Java并发编程实战"系列的第11天,今天我们聚焦于并发设计模式。并发设计模式是解决多线程环境下常见问题的经典解决方案,它们不仅提供了优雅的设计思路,还能显著提升系统的性能…...

GraphRAG优化新思路-开源的ROGRAG框架
目前的如微软开源的GraphRAG的工作流程都较为复杂,难以孤立地评估各个组件的贡献,传统的检索方法在处理复杂推理任务时可能不够有效,特别是在需要理解实体间关系或多跳知识的情况下。先说结论,看完后感觉这个框架性能上不会比Grap…...