当前位置: 首页 > news >正文

【多线程案例】生产者消费者模型(堵塞队列)

文章目录

    • 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();}
}

运行结果:
1

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();}
}

1111
1 因为t2 未启动,所以只能生产元素,当生产10个元素后,队列满了,进入堵塞,等待被唤醒;
2 因为t1生产时,每次都会休眠,线程执行非常迅速,所以队列一直出元素,直到队列为空,进入堵塞,等待被唤醒;
3生产一个元素消费一个元素。

相关文章:

【多线程案例】生产者消费者模型(堵塞队列)

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

数据结构与算法基础-学习-30-插入排序之直接插入排序、二分插入排序、希尔排序

一、排序概念 将一组杂乱无章的数据按一定规律顺次排列起来。 将无序序列排成一个有序序列&#xff08;由小到大或由大到小&#xff09;的运算。 二、排序方法分类 1、按数据存储介质 名称描述内部排序数据量不大、数据在内存&#xff0c;无需内外交换存交换存储。外部排序…...

Qt+C++桌面计算器源码

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

kubesphere安装Maven+JDK17 流水线打包

kubesphere 3.4.0版本&#xff0c;默认支持的jav版本是8和11&#xff0c;不支持17 。需要我们自己定义JenKins Agent 。方法如下&#xff1a; 一、构建镜像 1、我们需要从Jenkins Agent的github仓库拉取master最新源码&#xff0c;最新源码里已经支持jdk17了。 git clone ht…...

百度搜索清理大量低质量网站

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 据部分站长爆料&#xff1a;百度大规模删低质量网站的百度资源站长平台权限&#xff0c;很多网站都被删除了百度站长资源平台后台权限&#xff0c;以前在百度后台添加的网站大量被删除&#xff01;…...

WPF数据模板

样式提供了基本的格式化能力&#xff0c;但它们不能消除到目前为止看到的列表的最重要的局限性&#xff1a;不管如何修改ListBoxItem&#xff0c;它都只是ListBoxItem&#xff0c;而不是功能更强大的元素组合。并且因为每个ListBoxItem只支持单个绑定字段&#xff0c;所以不可能…...

浙江绿农环境:将废弃矿山变耕地,为生态文明贡献力量

近年来&#xff0c;随着可持续发展理念在中国乃至全球的日益普及&#xff0c;浙江绿农生态环境有限公司以其独特的创新和实践&#xff0c;成为了绿色发展的典范&#xff0c;在奋进新时代、建设新天堂的背景下&#xff0c;绿农环境在杭州市固废治理行业迈出坚实的步伐&#xff0…...

HTML/CSS盒子模型

盒子&#xff1a;页面中的所有的元素&#xff08;标签&#xff09;&#xff0c;都可以看做一个盒子&#xff0c;由盒子将页面中的元素包含在一个矩形区域内&#xff0c;通过盒子的视角更加方便的进行页面布局 盒子模型的组成&#xff1a; 内容区域&#xff08;content&#xff…...

《Java面向对象程序设计》学习笔记——CSV文件的读写与处理

​笔记汇总&#xff1a;《Java面向对象程序设计》学习笔记 笔记记录的不是非常详实&#xff0c;如果有补充的建议或纠错&#xff0c;请踊跃评论留言&#xff01;&#xff01;&#xff01; 什么是CSV文件 CSV文件的定义 CSV 是英文 comma-separated values 的缩写&#xff0…...

opencv 案例05-基于二值图像分析(简单缺陷检测)

缺陷检测&#xff0c;分为两个部分&#xff0c;一个部分是提取指定的轮廓&#xff0c;第二个部分通过对比实现划痕检测与缺角检测。本次主要搞定第一部分&#xff0c;学会观察图像与提取图像ROI对象轮廓外接矩形与轮廓。 下面是基于二值图像分析的大致流程 读取图像将图像转换…...

Elasticsearch入门介绍

应用场景 1 它提供了强大的搜索功能&#xff0c;可以实现类似百度、谷歌等搜索。 2 可以搜索日志或者交易数据&#xff0c;用来分析商业趋势、搜集日志、分析系统瓶颈或者运行发展等等 3 可以提供预警功能&#xff08;持续的查询分析某个数据&#xff0c;如果超过一定的值&a…...

QML Book 学习基础3(动画)

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

Lesson4-3:OpenCV图像特征提取与描述---SIFT/SURF算法

学习目标 理解 S I F T / S U R F SIFT/SURF SIFT/SURF算法的原理&#xff0c;能够使用 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流程控制

流程控制 顺序结构、条件结构、循环结构&#xff0c;顺序结构由自上而下的语句构成&#xff0c;条件结构由if、match-case构成&#xff0c;循环结构由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工具的配置等步骤&#xff08;网上链接也比较多&#xff09; 下列链接非本人的&#xff08;如果使用pip 在命令行安装过pyqt5以及tools&#xff0c;那么就可以跳过…...

CXL.mem S2M Message 释义

&#x1f525;点击查看精选 CXL 系列文章&#x1f525; &#x1f525;点击进入【芯片设计验证】社区&#xff0c;查看更多精彩内容&#x1f525; &#x1f4e2; 声明&#xff1a; &#x1f96d; 作者主页&#xff1a;【MangoPapa的CSDN主页】。⚠️ 本文首发于CSDN&#xff0c…...

设计模式—外观模式(Facade)

目录 一、什么是外观模式&#xff1f; 二、外观模式具有什么优点吗&#xff1f; 三、外观模式具有什么缺点呢&#xff1f; 四、什么时候使用外观模式&#xff1f; 五、代码展示 ①、股民炒股代码 ②、投资基金代码 ③外观模式 思维导图 一、什么是外观模式&#xff1f;…...

Stack Overflow开发者调查发布:AI将如何协助DevOps

Stack Overflow 发布了开创性的2023年度开发人员调查报告 [1]。报告对 90,000 多名开发人员进行了调查&#xff0c;全面展示了当前软件开发人员的体验。接下来&#xff0c;本文将重点介绍几项重要发现&#xff0c;即重要编程语言和工具偏好、人工智能在开发工作流程中的应用以及…...

去掉鼠标系列之二:Sublime Text快捷键使用指南

系列之二&#xff0c;Sublime Text。 Sublime Text 是我们常用的文本工具&#xff0c;常常要沉浸如其中使用&#xff0c;而不希望被鼠标打扰&#xff0c;所以也记录一下。 学会下面这些快捷键&#xff0c;基本上就不需要移动鼠标啦。 1&#xff0c;CtrlK&#xff0c;CtrlV …...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...

SQL Server 触发器调用存储过程实现发送 HTTP 请求

文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...

区块链技术概述

区块链技术是一种去中心化、分布式账本技术&#xff0c;通过密码学、共识机制和智能合约等核心组件&#xff0c;实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点&#xff1a;数据存储在网络中的多个节点&#xff08;计算机&#xff09;&#xff0c;而非…...