阻塞队列(模拟实现)
概念
阻塞队列是带有阻塞功能的队列
特性
当队列满的时候,继续入队列,就会出现阻塞,阻塞到其他线程从队列中取走元素为止
当队列空的时候,继续出队列,也会发生阻塞,阻塞到其他线程往队列中添加元素为止
特点
阻塞队列有着解耦合和削峰填谷的主要特点
1.解耦合
两个服务器A,B,服务器A负责输送用户请求给服务器B,服务器B负责解决用户请求,但是两个服务器之间不是直接联系起来的,而是有一个阻塞队列在两个服务器之间,服务器A将请求输送给阻塞队列,服务器B从阻塞队列中获取请求,这样两个服务器之间就不是直接联系,耦合性就被降低。
耦合性降低可以避免出现一个服务器发生错误导致另一个服务器也发生错误的情况
2.削峰填谷
同样是两个服务器A,B,服务器A负责输送用户请求给服务器B,有一个阻塞队列在两个服务器之间,当出现莫种特殊情况,导致服务器A输送大量的数据到队列中,由于阻塞队列满了再添加数据就会发生阻塞等待,所以服务器B处理数据的节奏不会被影响,但要是没有阻塞队列,服务器A和服务器B是直接连接的话,很可能服务器A输送大量的请求给服务器B会导致服务器B崩溃
系统提供的阻塞队列的使用
BlockingQueue<Integer> queue=new ArrayBlockingQueue(); //底层是顺序表
BlockingQueue<Integer> queue=new LinkedBlockingQueue(); //底层是链表
BlockingQueue<Integer> queue=new PriorityBlockingQueue(); //底层是优先级队列(堆)
调用put方法是添加数据到队列中,调用take方法是弹出队列中的数据,由于BlockingQueue实现了Queue接口,所以它也有offer和poll等方法,但只有put和take方法是带阻塞的,所以推荐使用put和take方法
代码展示
class MyBlockingQueue{//用循环顺序表来作为阻塞队列的底层实现private String[]items=new String[1000];//数据存在的范围是[head,tail)//避免出现内存可见性和指令重排序的问题,要对变量加上volatile//指向头部的指针private volatile int head=0;//指向尾部的指针private volatile int tail=0;//记录阻塞队列中的数据个数private volatile int size=0;//put和take方法在多线程中涉及到多个线程改变同一个变量,所以要加上锁//向阻塞队列插入数据public void put(String elem) throws InterruptedException {synchronized(this){//判断队列是否满了while (size>=items.length){ //不一定阻塞等待是被notify正常唤醒的,也就不一定队列真的不满了,所以要用while循环多次判断//直到真的队列没满才进行接下来的操作(wait进行阻塞等待推荐和while一起使用,多次判断是否满足唤醒条件)this.wait(); //当队列满了就进入阻塞等待}items[tail]=elem;tail++;size++;if(tail>=items.length){tail=0;}this.notify(); //当向阻塞队列插入数据后,便可以唤醒弹出数据的阻塞状态}}//弹出阻塞队列中的数据public String take() throws InterruptedException {synchronized(this){//判断阻塞队列是否为空while (size==0){//不一定阻塞等待是被notify正常唤醒的,也就不一定队列真的不为空,所以要用while循环多次判断//直到真的队列不为空才进行接下来的操作(wait进行阻塞等待推荐和while一起使用,多次判断是否满足唤醒条件)this.wait();}String elem=items[head];head++;size--;if(head>=items.length){head=0;}this.notify(); //弹出一个数据后队列不满了就可以唤醒插入数据的阻塞状态return elem;}}}
代码分析
1.该代码中实现阻塞队列的底层结构是很简单的循环数组
2.由于要满足多线程编程,而put和take操作涉及到多个线程修改同一个变量的问题,所以需要用synchronized给put和take方法加锁,而为了防止出现内存可见性和指令重排序问题,对于在多线程中要进行读取修改的变量加上volatile关键字,防止编译器进行优化。
关于synchronized和内存可见性和指令重排序可以看线程安全问题,线程安全问题(内存可见性),线程安全问题(指令重排序)
3.如何实现阻塞呢?在put方法中,如果队列满了,那就要进入阻塞等待,就用synchronized加锁的对象调用wait方法进入阻塞等待,只有当take方法执行成功,才能调用notify唤醒put方法中阻塞等待的线程。
同样在take方法中,如果队列空了,那就要进入阻塞等待,就用synchronized加锁的对象调用wait方法进入阻塞等待,只有当put方法执行成功,才能调用notify唤醒take方法中阻塞等待的线程。关于wait于notify可以看通过wait和notify来协调线程执行顺序
4.put和take方法要对同一个对象进行加锁,因为put和take中要修改的变量有相同的,所以当多个线程调用put和take方法时存在线程安全问题,所以要对同一个对象进行加锁。
5.判断是否进入阻塞等待的条件是一个while循环(推荐wait()与while一起使用),因为不一定阻塞等待wait是被notify正常唤醒的,也就不一定是否真的满足队列不满或者不空的条件,所以要进行多次判断,要是队列依然还是满或空的话就要再次进入阻塞等待
相关文章:
阻塞队列(模拟实现)
概念 阻塞队列是带有阻塞功能的队列 特性 当队列满的时候,继续入队列,就会出现阻塞,阻塞到其他线程从队列中取走元素为止 当队列空的时候,继续出队列,也会发生阻塞,阻塞到其他线程往队列中添加元素为止 特…...
VScode中python的相对路径与绝对路径 FileNotFoundError: [Errno 2] No such file or directory
VScode中,python里的相对路径是相对于当前工作目录来定位的,而当前的工作目录在VScode中下方的终端窗口会有提示: 说明此时的工作目录并非当前python文件所在的目录,而是C:\Users\xxxxx(你的用户名)。因此,使用VScode…...
Unity XML2——C#读写XML
一、XML 文件的存放位置 (一)只读不写的 XML 放在 Resouces 或者 StreamingAssets 文件夹下,详见 Unity基础3——Resources资源动态加载_weixin_53163894的博客-CSDN博客。 (二)动态存储的 XML 放在 Applica…...
带wiringPi库的交叉编译 ---宿主机x86Ubuntu,目标机ARMv8 aarch64(香橙派)
带wiringPi库的交叉编译如何进行 先交叉编译wiringPi库,编译出的库适合香橙派,这时候交叉编译可执行程序的平台和链接库的格式也是正确的,然后通过-I和-L来指定链接的wiringPi库的头文件和库的位置,但是现在还没有学习过…...
数据仓库基础知识
什么是数据仓库? 数仓,DataWarehouse,是一个 面向主题的、集成的、稳定的、与时间相关的 数据集合。 而这个数据集合的建立,是为了支持管理者的决策过程。 也就是说,我们通过建设数仓,为业务中的流程改进、…...
M 芯片的 macos 系统安装虚拟机 centos7 网络配置
centos 安装之前把网络配置配好或者是把网线插好 第一步找到这个 第二步打开网络适配器 选择图中所指位置 设置好之后 开机启动 centos 第三步 开机以后 编写网卡文件保存 重启网卡就可以了,如果重启网卡不管用,则重启虚拟机即可 “ ifcfg-ens160 ” 这…...
AcWing 3708. 求矩阵的鞍点
输入样例: 3 4 1 2 3 4 1 2 3 4 1 2 3 4输出样例: 1 4 4 2 4 4 3 4 4 #include<bits/stdc.h> using namespace std; const int N1010; int n,m,a[N][N],x[N],y[N],flag1; int main(){scanf("%d%d",&n,&m);for(int i1;i<n;i…...
web前端开发工程师的具体职责范本(合集)
web前端开发工程师的具体职责范本1 职责: 1.负责web前端架构的搭建,核心业务功能开发和核心代码编写。 2.配合产品经理,实现产品UI和交互方面的需求,持续界面优化,提升用户体验。 3.参与相关业务需求变更评审。 4.…...
从源程序到可执行文件的四个过程
从源程序到可执行文件的四个过程 预处理编译汇编链接 程序要运行起来,必须要经过四个步骤:预处理、编译、汇编和链接,如下图所示: -E选项:提示编译器执行完预处理就停下来,后边的编译、汇编、链接就先不执…...
C++部署学习
gcc -E src/main.c -o src/main.i gcc -S src/main.c -o src/main.s gcc -C src/main.c -o src/main.o gcc src/main.c -o exec ./exec...
linux下lazarus开发ide里 BGRAControls控件库comboBox示例
下载开发工具 ftp://ftp.freepascal.org/pub/lazarus/releases/Lazarus%20Linux%20amd64%20DEB/Lazarus%202.2.6/https://sourceforge.net/projects/lazarus/files/Lazarus%20Linux%20amd64%20DEB/Lazarus%202.2.6/ sourceforge下载可能比较慢,选择 下载有问题&…...
Redis学习路线(9)—— Redis的场景使用
默认做好了其它的前提,只专注于Redis使用 一、短信登录 在没有Redis数据库时,我们会基于Session实现登录(利用令牌进行授权),是怎么实现的呢? (一)基于Session的短信登录功能 1、…...
糟了,数据库主从延迟了!
前言 在实际的生产环境中,由单台MySQL作为独立的数据库是完全不能满足实际需求的,无论是在安全性,高可用性以及高并发等各个方面 因此,一般来说都是通过集群主从复制(Master-Slave)的方式来同步数据&…...
VUE,子组件给父组件传递参数,props 自定义属性,ref
<template><div><!-- 子传父 --><!-- 通过父组件给子组件传递函数类型的props实现:子给父传递数据 --><AA :getAAname"getAAname"/><h1>AA:{{aaname}}</h1><!-- 通过父组件给子组件绑定一个自定…...
【Oracle系列】- Oracle数据迁移
【Oracle系列】- Oracle数据迁移 文章目录 【Oracle系列】- Oracle数据迁移一、概述二、数据迁移方案三、模拟迁移方案四、迁移步骤五、迁移方案及其实施细则5.1 exp/imp逻辑备份与恢复5.2 Storage存储迁移5.3 利用data guard迁移 一、概述 最近在做公司软件系统盘点时&#x…...
Linux环境安装MySQL(详细教程)
1、下载MySQL MySQL官网:MySQLhttps://www.mysql.com/ 下载社区版(免费,但不提供技术支持) 简单说明一下rpm和tar包的区别: tar 只是一种压缩文件格式,所以,它只是把文件压缩打包 rpm…...
23. Mysql中的排序规则
文章目录 Mysql中的排序规则1. 数据库默认的排序规则2. 查看表的排序规则2.1 查看表排序规则2.2 查看字段排序规则 3.修改排序规则3.1 修改库3.2 修改表3.3 修改字段 Mysql中的排序规则 1. 数据库默认的排序规则 mysql8的默认排序方式是 utf8mb4_0900_ai_ci mysql5的默认排序…...
MongoDB 基础学习记录
MongoDB 基础 mongoDB 是由 C语言编写,基于分布式文件存储的开源数据库系统,是一个 nosql 数据库. 在高负载的情况下,添加更多的节点,保证服务器性能,MongoDB 旨在为 web 引用提供可扩展的高性能存储解决方案,将数据存储为给文档, 数据结构由键值(key,value)对组成,MongoDB 文…...
Visual Studio2022报错 无法打开 源 文件 “openssl/conf.h“解决方式
目录 问题起因问题解决临时解决方案 问题起因 近一段时间有了解到Boost 1.82.0新添加了MySQL库,最近一直蠢蠢欲动想要试一下这个库 所以就下载了源码并进行了编译(过程比较简单,有文档的) 然后在VS2022中引入了Boost环境…...
【更新公告】Airtest更新至1.3.0.1版本
1. 前言 本次更新为Airtest库更新,版本提升至1.3.0.1版本,主要新增了一些iOS设备相关的装包等接口,以及封装了一些tidevice常用接口。更多更新详情,详见我们下文的描述。 2. 新增iOS设备接口 1)iOS安装接口…...
QueryExcel:解放双手的Excel批量查询神器,告别Ctrl+F的繁琐时代
QueryExcel:解放双手的Excel批量查询神器,告别CtrlF的繁琐时代 【免费下载链接】QueryExcel 多Excel文件内容查询工具。 项目地址: https://gitcode.com/gh_mirrors/qu/QueryExcel 在日常工作中,你是否也曾被海量Excel文件中的数据查找…...
AI赋能软件测试:基于PyTorch视觉模型实现自动化GUI测试脚本生成效果演示
AI赋能软件测试:基于PyTorch视觉模型实现自动化GUI测试脚本生成效果演示 1. 效果亮点预览 想象一下这样的场景:一个AI系统正在自动测试你的软件界面,它能像人类测试工程师一样"看"懂屏幕上的每个元素,发现那些传统脚本…...
【仅限头部金融科技团队内部流通】FastAPI 2.0 AI流式响应安全加固方案:防内存溢出、防连接耗尽、防Token泄露(含OWASP ASVS v4.0合规对照表)
第一章:FastAPI 2.0 AI流式响应安全加固方案全景概览FastAPI 2.0 引入了对 Server-Sent Events(SSE)与异步生成器的原生增强支持,使大语言模型(LLM)的流式响应(如 token-by-token 输出ÿ…...
智能车调参手记:我用Kp=200, Ki=60, Kd=40让小车稳如老狗
智能车调参手记:我用Kp200, Ki60, Kd40让小车稳如老狗 凌晨三点的实验室里,咖啡杯已经见底,眼前的智能车在测试跑道上又一次冲出了弯道。这已经是本周第七次熬夜调试,上坡时的速度波动问题始终困扰着我们。就在准备放弃的时候&…...
MongoDB(70)如何使用副本集进行备份?
使用副本集进行备份是一个常见的MongoDB备份策略,因为副本集提供了数据冗余和高可用性。通过从副本集中读取数据,可以在不影响主节点的情况下进行备份。以下是详细的步骤和示例代码,展示如何使用 MongoDB 副本集进行备份。方法一:…...
Qwen2.5-VL图文助手体验:RTX 4090极速推理,支持对话历史和一键清空
Qwen2.5-VL图文助手体验:RTX 4090极速推理,支持对话历史和一键清空 如果你手头有一张RTX 4090显卡,想找一个能看懂图片、能聊天、还能帮你处理各种视觉任务的本地AI助手,那么今天要聊的这个工具,你可能会很感兴趣。 …...
Deepin系统远程桌面实战:从零配置xrdp服务到Windows无缝连接
Deepin系统远程桌面实战:从零配置xrdp服务到Windows无缝连接 在跨平台协作成为常态的今天,远程桌面技术让不同操作系统间的无缝协作成为可能。对于使用Deepin系统的用户而言,如何高效地通过Windows设备远程访问和控制Deepin桌面,是…...
Realistic Vision V5.1 提示词工程入门:C语言基础思维在Prompt编写中的应用
Realistic Vision V5.1 提示词工程入门:C语言基础思维在Prompt编写中的应用 如果你有C语言的编程经验,现在想玩转AI图像生成,特别是像Realistic Vision V5.1这样的写实风格模型,那这篇文章就是为你准备的。很多人觉得写提示词&am…...
Seqlist 顺序表 的实现c语言
本小结重点: 你将学到 函数基础 传值传地址的区别结构体指针 简单循环控制 理解物理结构与存储结构的区别多文件分布 简单来说就是对动态数组进行函数封装,简化了很多功能所以很多就是对数组的利用,但更多是对结构体数组,所…...
【读书笔记】《在远远的背后带领》
《在远远的背后带领》书话整理书名由来 "在远远的背后带领"这个书名,源于作者对十余年养育实践的回顾与思考。她发现,父母养育孩子容易走两个极端: 过度控制:强迫孩子按照自己的想法行事,结果双方俱疲&#…...
