【JaveEE】多线程之阻塞队列(BlockingQueue)
目录
1.了解阻塞队列
2.生产者消费者模型又是什么?
2.1生产者消费者模型的优点
2.1.1降低服务器与服务器之间耦合度
2.1.2“削峰填谷”平衡消费者和生产的处理能力
3.标准库中的阻塞队列(BlockingQueue)
3.1基于标准库(BlockingQueue)实现一个简单的阻塞队列的应用
4.基于循环队列模拟是实现阻塞队列
4.1 put()方法
4.2 take()方法
4.3put方法和take方法是如何被唤醒
1.了解阻塞队列
阻塞队列是一种特殊的队列. 也遵守 "先进先出" 的原则.
阻塞队列顾名思义就是带有阻塞特性的队列的,它是如何运行的呢?
答: 1.当队列为空时,尝试出队列,就会发生阻塞,直到队列不空为止。
2.当队列为满时,尝试入队列,就会发送阻塞,直到队列不满为止
阻塞队列在 多线程中非常有用,它可以调节生产者和消费者之间的关系,当生产者生产的资源太多,以至于消费者无法完全消费完,那么可以让生产者阻塞,达到生产、消费平衡的作用。
2.生产者消费者模型又是什么?
生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题。
生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取。
它将所有工作分工明确,参考下面这个例子:
有4个人我们一起包饺子,我们每个人都各顾各的,每个人都得做擀面皮和包饺子,如果这样的话,每个人的包饺子的效率都不是很高。若我们进行分工,1个人负责擀面皮,3个人负责包饺子,擀面皮的不管包饺子的是如何包,包饺子的不管擀面皮的是如何擀的。在第二种方式中擀面皮的就可以看作生产者,包饺子的就可以看作消费者。
2.1生产者消费者模型的优点
2.1.1降低服务器与服务器之间耦合度
看如下解读:开始时A服务器和B服务器通过阻塞对象进行交互,若B服务器挂了,那么我们可以迅速的做出反应,参考阻塞队列进行重新加载B服务器。还有就是若A服务器业务服务器,B服务器是实现业务的服务区,因为业务服务器需要时常更新代码,因此可以阻塞队列相当于一个缓存区。
2.1.2“削峰填谷”平衡消费者和生产的处理能力
比如在 "秒杀" (购买物品)场景下, 服务器同一时刻可能会收到大量的支付请求. 如果直接处理这些支付请求,服务器可能扛不住(每个支付请求的处理都需要比较复杂的流程). 这个时候就可以把这些请求都放到一个阻塞队列中, 然后再由消费者线程慢慢的来处理每个支付请求.在这里就起到了削峰的效果。
“ 削峰填谷”我们可以联想到三峡大坝:
三峡可谓是“功在当代,利在千秋”,为何这样说?三峡大坝它可不仅仅只是发电用的,它还有其他的功能。当到达雨季时,三峡上游的水向下流的会比往常多,这时开始关闸蓄水,防止下游发生洪灾,这就是“削峰”,过了雨季,下游需要灌溉庄稼,但是下游水又少了,这时打开闸门进行放水,造福下游,这就是“填谷”。
在购物系统中,我们就可以将秒杀时突然猛增的用户请求比喻成雨季的雨水,我们通过阻塞队列进行蓄洪,当在平常时,没那么多的用户请求时,我们就是慢慢的解决用户的请求比喻成开闸放水。
3.标准库中的阻塞队列(BlockingQueue)
BlockingQueue的成员:
- ArrayBlockingQueue:基于数组的阻塞队列实现
- LinkedBlockingQueue:基于链表的阻塞队列
- PriorityBlockingQueue:基于优先队列的阻塞队列
- BlockingQueue:这个是实现阻塞队列的接口,继承与Queue
常用方法介绍:
方法 | 说明 |
boolean add(E e) | 将指定的元素插入到此队列中,如果可以立即执行此操作而不违反容量限制, 如果当前没有可用空间,则抛出IllegalStateException |
void put(E e) | 将指定的元素插入到此队列中,等待空格可用。 |
E take() | 检索并删除此队列的头,如有必要,等待元素可用。 |
boolean offer(E e) | 将指定的元素插入到此队列中,如果可以立即执行此操作,而不会违 反容量限制, true在成功时 false如果当前没有可用空间,则返回false。 |
boolean offer (E e, long timeout, TimeUnit unit) | 将指定的元素插入到此队列中,等待指定的等待时间(如有必要)才能使空间变 得可用。 |
E poll (long timeout, TimeUnit unit) | 检索并删除此队列的头,等待指定的等待时间(如有必要)使元素变为可用。 |
注意:在这个些方法中,只有put()方法和take()方法带有阻塞特性,其他的方法不具备阻塞特性。
3.1基于标准库(BlockingQueue)实现一个简单的阻塞队列的应用
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;public class testDemo1 {public static void main(String[] args) throws InterruptedException {BlockingQueue<Integer> queue=new LinkedBlockingDeque<>();//生产者Thread producer=new Thread(()->{int i=0;while (true) {try {System.out.println("生产:"+i);queue.put(i);i++;Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});producer.start();//消费者Thread customer=new Thread(()-> {while (true) {try {int value=queue.take();System.out.println("消费:"+value);} catch (InterruptedException e) {e.printStackTrace();}}});customer.start();}
}
代码运行结果:
4.基于循环队列模拟是实现阻塞队列
这此次模拟实现中,仅模拟了put()方法,和take()方法。
若有对循环队列不了解的话,可以参考下方链接了解循环队列:【数据结构趣味多】循环队列https://blog.csdn.net/qq_65228171/article/details/128613550?spm=1001.2014.3001.5501
代码实现如下:
public class MyBlockingDeque {private int[] items=new int[1000];//头指针volatile private int head;//尾指针volatile private int tail;//队列中元素数量volatile private int size;synchronized public void put(int value) throws InterruptedException {//如果队列已满,阻塞等待while (size == items.length) {this.wait();}items[tail]=value;tail++;//如果队列满了,从头再来(循坏队列思想)if(tail==items.length) {tail=0;}size++;//唤醒takethis.notify();}synchronized public int take() throws InterruptedException {while (size==0){//等待放入元素,等待put唤醒this.wait();}int value=items[head];head++;//如果头到了队尾,重新加载if(head == items.length) {head=0;}size--;this.notify();return value;}
}
4.1 put()方法
put 方法是向队列中存放数据,因此第一步我们需要判断队列满没满,若队列满了的话,就让队列通过wait方法进入阻塞状态,等待唤醒。若队列没有满,就将数据放入到尾指针所指位置,让尾指针向后移动一位;当尾指针达到数组的长度时,我们就需要重置尾指针了。
synchronized public void put(int value) throws InterruptedException {//如果队列已满,阻塞等待while (size == items.length) {this.wait();}items[tail]=value;tail++;//如果队列满了,从头再来(循坏队列思想)if(tail==items.length) {tail=0;}size++;//唤醒takethis.notify();}
4.2 take()方法
take 方法是在队列中拿取数据,有两种情况,若队列空,发生阻塞,直到put进来数据,若不为空,拿到数据,头指针向后走,如果头指针达到数组长度,重置头指针,最后返回value。
synchronized public int take() throws InterruptedException {while (size==0){//等待放入元素,等待put唤醒this.wait();}int value=items[head];head++;//如果头到了队尾,重新加载if(head == items.length) {head=0;}size--;//唤醒putthis.notify();return value;}
4.3put方法和take方法是如何被唤醒的
1.当存入数据时,队列为满的时候,队列就会通过wait方法使线程进入阻塞态,它什么时候被唤醒呢?队列被拿走一个数据时,被唤醒,这个唤醒是在take中唤醒的,take拿走一个数据队列不为满,唤醒put。
2. 当拿去数据时,队列为空的时候,队列会通过while判断,让线程进入阻塞态,当有新的数据被放入时,take就会被唤醒。
写在最后:
以上就是本文全部内容,如果对你有所帮助,希望能留下你的点赞+关注,我会更加努力的更新内容!非常感谢🧡🧡🧡
若本篇文章有错误的地方,欢迎大佬们指正!
相关文章:
【JaveEE】多线程之阻塞队列(BlockingQueue)
目录 1.了解阻塞队列 2.生产者消费者模型又是什么? 2.1生产者消费者模型的优点 2.1.1降低服务器与服务器之间耦合度 2.1.2“削峰填谷”平衡消费者和生产的处理能力 3.标准库中的阻塞队列(BlockingQueue) 3.1基于标准库(Bloc…...
分布式ELK日志监控系统环境搭建
文章目录1.1为什么需要监控项目日志1.2ELK日志监控系统介绍1.3ELK的工作流程1.4ELK环境搭建1.4.1Elasticsearch的安装1.4.2Kibana的安装1.4.3Logstash的安装1.4.4数据源配置1.4.5日志监测测试1.4.6日志数据可视化展示1.1为什么需要监控项目日志 项目日志是记录项目运行过程中产…...
【数据结构刷题集】链表经典习题
😽PREFACE🎁欢迎各位→点赞👍 收藏⭐ 评论📝📢系列专栏:数据结构刷题集🔊本专栏涉及到题目是数据结构专栏的补充与应用,只更新相关题目,旨在帮助提高代码熟练度&#x…...
JavaSE(3.27) 异常
学习不要眼高手低,学习是一点点积累的。即使你现在很菜,坚持学一个学期不会差的!只要花时间学习,每天都是进步的,这些进步可能你现在看不到,但是不要小瞧了积累效应,30天,60天&#…...
【看门狗】我说的是定时器不是狗啊
单片机在运行中死机了,你或许只能按2下电源键(重启)或1下复位键。 这里简单说一下重启和复位: 从RESET引脚复位,只有MCU复位。而外设看情况,有的可能会有MCU同步复位或者重新初始化。也有可能一些保持复位…...
24万字智慧城市顶层设计及智慧应用解决方案
本资料来源公开网络,仅供个人学习,请勿商用,如有侵权请联系删除。部分资料内容: 4.8 机房消防系统 4.8.1消防系统概况 根据本工程机房消防系统的特殊要求,整个消防系统由火灾报警系统、消防联动系统和气体灭火系统三部…...
跨境电商卖家工具——跨境卫士内容介绍
一、简介 跨境卫士是一款集合多种跨境电商工具的综合软件,由知名跨境电商服务商跨境通开发。跨境卫士可以帮助卖家完成海外物流管理、订单处理、报关报税、市场营销等多项任务,同时还提供数据分析、客户服务、运营管理等一系列支持功能,方便卖…...
Redis 常用基本命令
关于 redis 的常用基本命令 目录 关于 redis 的常用基本命令 1. 关于 key 的操作 2. HyperLogLog 求近似基数 3. 排序相关命令 4. Limit 限制查询 1. 关于 key 的操作 判断某个 key 是否存在 # 格式: exists key exists name# 存在name 返回1 # 不存在name 返回0 查找或…...
【Leetcode】队列的性质与应用
文章目录225. 用队列实现栈示例:提示:分析:题解:622. 设计循环队列示例:提示:分析:题解:225. 用队列实现栈 请你仅使用两个队列实现一个后入先出(LIFO)的栈&…...
开启新航路,拓尔思发力AIGC市场 | 爱分析调研
2022年,随着AI聊天机器人GhatGPT在世界范围内持续火爆,极具创意、表现力、个性化且能快速迭代的AIGC技术成功破圈,成为全民讨论热点。 AIGC是指在确定主题下,由算法模型自动生成内容,包括单模态内容如文本、图像、音频…...
RK3568平台开发系列讲解(调试篇)Linux 内核的日志打印
🚀返回专栏总目录 文章目录 一、dmseg 命令二、查看 kmsg 文件三、调整内核打印等级沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将 Linux 内核的日志打印进行梳理。 一、dmseg 命令 在终端使用 dmseg 命令可以获取内核打印信息,该命令的具体使用方法如下所…...
hadoop之MapReduce框架原理
目录 MapReduce框架的简单运行机制: Mapper阶段: InputFormat数据输入: 切片与MapTask并行度决定机制: job提交过程源码解析: 切片逻辑: 1)FileInputFormat实现类 进行虚拟存储 &#x…...
JavaEE简单示例——SpringMVC的简单数据绑定
简单介绍: 在前面我们介绍过如何将我们自己创建的类变成一个servlet来处理用户发送的请求,但是在大多数的时候,我们在请求 的时候会携带一些参数,而我们现在就开始介绍我们如何在Java类中获取我们前端请求中携带的参数。首先&…...
耗时的同步请求自动转异步请求
耗时的同步请求自动转异步请求问题描述问题处理代码实现问题描述 现在在项目中碰到一个情况,导出数据到excel,在数据量比较下的时候直接下载,在数据量比较大时保存到服务的文件列表,后续再供用户下载。 也就是需要避免前端因后端…...
React常见的hook
目录 useState useEffect useRef useContext useCallback useMemo useState const [初始值,修改值的方法] useState( 初始值 ) 我们用useState定义一个初始值,可以打印看一下结果 console.log(useState(10)) // [10, ƒ] 结果是一个数组…...
Oracle集群管理ASM-扩容磁盘组报错ora-15137
1 内容描述 今日对19c集群磁盘组进行扩容, [rootdb1 ~]# oracleasm createdisk DATA7 /dev/sdm1 Writing disk header: done Instantiating disk: done [rootdb1 ~]# oracleasm createdisk DATA8 /dev/sdn1 Writing disk header: done Instantiating disk: done 使…...
TryHackMe-biteme(boot2root)
biteme 远离我的服务器! 端口扫描 循例 nmap Web枚举 打开一看是一个默认页面 扫一波 打thm这么久,貌似还是第一次见带验证码的登录 信息有限,对着/console再扫一波 查看/securimage 但似乎没有找到能利用的信息 回到console, 在源码发现…...
vue开发常用的工具有哪些
个人简介:云计算网络运维专业人员,了解运维知识,掌握TCP/IP协议,每天分享网络运维知识与技能。座右铭:海不辞水,故能成其大;山不辞石,故能成其高。个人主页:小李会科技的…...
数组,排序,查找
数组可以存放多个同一类型的数据,数组也是一种数据类型,是引用类型。 数组可以通过下标来访问元素下标是从0开始编号的比如第一个元素就是hens[0]数组定义,数据类型 数组名[] new 数据类型[大小];int a[] new int[5];动态初始化 import ja…...
redis中序列化后的对象后当如何修改
redis中序列化Redis 中存储的序列化对象是不可变需要频繁修改对象属性, 我存储对象为hash结构如何?总结君问归期未有期,巴山夜雨涨秋池。——唐代李商隐《夜雨寄北》 Redis 中存储的序列化对象是不可变 在 Redis 中存储的序列化对象是不可变的,因为它们…...
膜拜!阿里自爆十万字Java面试手抄本,脉脉一周狂转50w/次
最近,一篇题为《阿里十万字Java面试手抄本》的文章在社交媒体平台上引起了广泛关注。这篇文章由一位阿里工程师整理了阿里Java面试的经验,并分享给了大家。这篇文章一经发布,就在短时间内获得了数十万的转发量,让许多Java程序员受…...
Yolov5改进: Yolov5-FasterNet网络推理加速
文章目录 1. FasterNet介绍1. 1 FasterNet性能1.2 FasterNet作为Backbone2. 基于C3-Faster实现Yolov5 轻量化2.1 C3-Faster的实现2.2 C3-Faster 在YOLOv5中的使用(1) 在common.py 中添加`C3-Faster`代码(2) 修改yolo.py 中的代码(2) 修改yolov5 yaml文件3. 训练1. FasterNet介绍…...
在ubuntu下安装五笔输入法(百度输入法)
想要在ubuntu下安装一款合适的五笔输入法,不是一件容易的事。现在我找到了一个好用的输入法分享给大家。 环境:Ubuntu22.04桌面版。 软件:百度Linux输入法-支持全拼、双拼、五笔 步骤一: 需要大家先下载百度的五笔输入法。 http…...
python自动发送邮件(html、附件等),qq邮箱和网易邮箱发送和回复
在python中,我们可以用程序来实现向别人的邮箱自动发送一封邮件,甚至可以定时,如每天8点钟准时给某人发送一封邮件。今天,我们就来学习一下,如何向qq邮箱,网易邮箱等发送邮件。 一、获取邮箱的SMTP授权码。…...
数学-快速幂
从一个简单的问题说起: 给出整数m,n和p,要求计算(m ^ n) % p的结果。 #include <iostream> using namespace std;int main() {long long m, n, p;cin >> m >> n >> p;long long ans 1;for (long long i 0; i < …...
DevEco鸿蒙应用开发-第一个App
目录下载开发环境创建工程登录华为账户测试应用下载开发环境 前往官网下载 DevEco 开发环境:https://developer.harmonyos.com/cn/develop/deveco-studio#download 下载并安装,请记住你选择的 IDE 与 SDK 安装位置,后续可能会用到ÿ…...
又一款全新的基于 GPT4 的 Python 神器Cursor,关键还免费
chartgpt大火之后,随之而来的就是一大类衍生物了。 然后,今天要给大家介绍的是一款基于GPT4的新一代辅助编程神器——Cursor。 它最值得介绍的地方在于它免费,我们可以直接利用它来辅助我们编程,真正做到事半功倍。 注意&#…...
CSS的浮动(下)
🌟所属专栏:前端只因变凤凰之路🐔作者简介:rchjr——五带信管菜只因一枚😮前言:该系列将持续更新前端的相关学习笔记,欢迎和我一样的小白订阅,一起学习共同进步~👉文章简…...
软件测试-性能测试流程
压测任务具体包含: 0.前期准备 尽量参与业务需求评审,可以对业务有更深入的了解,了解哪些功能是核心功能,哪些可能存在性能瓶颈,以便在性能需求评审的时候能给出有建设性的意见 1.性能需求分析、评审 明确测试范围(哪些业务接口)、目标(tps、rt、成功率) 关于性能需…...
【python实操】年轻人,别用记事本保存数据了,试试数据库吧
为什么用数据库? 数据库比记事本强在哪? 答案很明显,你的文件很多时候都只能被一个人打开,不能被重复打开。当有几百万数据的时候,你如何去查询操作数据,速度上要快,看起来要清晰直接 数据库比我…...
菏泽做网站/优化公司网站
使用root用户操作,报错误 rm: cannot remove ryukd.sh: Operation not permitted 1. chmod的底层实现是chattr命令,但是chattr命的功能更为强大,甚至可以锁定文件,即使root用户也操作不了此文件 2. chattr是用来更改文件属性&am…...
室内设计网站排行榜前十名知乎/全达seo
JPA进阶 一、主键生成策略 (一)主键实现的两种类型 1.自然主键 有业务含义的主键JPA不定义GeneratedValue就可以了 2.代理主键 没有意义,用来区别每行的数据是不同的 (二) 四种主键生成策略 1.IDENTITY 自增策…...
wordpress 觉唯主题/阻断艾滋病的药有哪些
5G快来了,视频将会是跑在网络上流量最多的东西,短视频、长视频、电影、视频通话、视频监控,各种各样的,而在消费级领域,监控视频近些年也越来越受到关注和欢迎,从萤石摄像机的诞生、到一众互联网家用摄像机…...
抖音小店代运营/seo网站推广主要目的不包括
1)无法下发指令 发现是因为加载下发指令的xml文件在发布状态下没有权限, 这个在vs上调试没有问题 ,发布后才发现新问题。 2)无法实时查看运行状况 vs2017无法直接调试js,上次成功也好像是偶然,所以只能…...
高端网站建设专业营销团队/公司想做网络推广贵不
今天给大家介绍一个github仓库,收集了非常多的推荐系统的数据集,非常的全面,非常的实用,做推荐系统相关的同学可以收藏一下。 这些数据集在可作为基准的推荐系统中非常流行。 Douban:http://socialcomputing.asu.edu/…...
深圳网站建设联雅网络/郑州seo外包平台
【项目背景】 近年来,信息技术的飞速发展使人们获取、交流和处理信息的手段发生了巨大的变化,随着信息时代的到来,信息化发展也为公安工作带来了新的挑战和机遇。 随着全国电子政务进程的推进,国家提出了以“公安信息化工作”为核…...