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

阻塞队列(模拟实现)

概念

        阻塞队列是带有阻塞功能的队列

特性

        当队列满的时候,继续入队列,就会出现阻塞,阻塞到其他线程从队列中取走元素为止

        当队列空的时候,继续出队列,也会发生阻塞,阻塞到其他线程往队列中添加元素为止

特点

        阻塞队列有着解耦合和削峰填谷的主要特点

        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正常唤醒的,也就不一定是否真的满足队列不满或者不空的条件,所以要进行多次判断,要是队列依然还是满或空的话就要再次进入阻塞等待

相关文章:

阻塞队列(模拟实现)

概念 阻塞队列是带有阻塞功能的队列 特性 当队列满的时候&#xff0c;继续入队列&#xff0c;就会出现阻塞&#xff0c;阻塞到其他线程从队列中取走元素为止 当队列空的时候&#xff0c;继续出队列&#xff0c;也会发生阻塞&#xff0c;阻塞到其他线程往队列中添加元素为止 特…...

VScode中python的相对路径与绝对路径 FileNotFoundError: [Errno 2] No such file or directory

VScode中&#xff0c;python里的相对路径是相对于当前工作目录来定位的&#xff0c;而当前的工作目录在VScode中下方的终端窗口会有提示&#xff1a; 说明此时的工作目录并非当前python文件所在的目录&#xff0c;而是C:\Users\xxxxx(你的用户名)。因此&#xff0c;使用VScode…...

Unity XML2——C#读写XML

一、XML 文件的存放位置 &#xff08;一&#xff09;只读不写的 XML ​ 放在 Resouces 或者 StreamingAssets 文件夹下&#xff0c;详见 Unity基础3——Resources资源动态加载_weixin_53163894的博客-CSDN博客。 &#xff08;二&#xff09;动态存储的 XML ​ 放在 Applica…...

带wiringPi库的交叉编译 ---宿主机x86Ubuntu,目标机ARMv8 aarch64(香橙派)

带wiringPi库的交叉编译如何进行 先交叉编译wiringPi库&#xff0c;编译出的库适合香橙派&#xff0c;这时候交叉编译可执行程序的平台和链接库的格式也是正确的&#xff0c;然后通过-I和-L来指定链接的wiringPi库的头文件和库的位置&#xff0c;但是现在还没有学习过&#xf…...

数据仓库基础知识

什么是数据仓库&#xff1f; 数仓&#xff0c;DataWarehouse&#xff0c;是一个 面向主题的、集成的、稳定的、与时间相关的 数据集合。 而这个数据集合的建立&#xff0c;是为了支持管理者的决策过程。 也就是说&#xff0c;我们通过建设数仓&#xff0c;为业务中的流程改进、…...

M 芯片的 macos 系统安装虚拟机 centos7 网络配置

centos 安装之前把网络配置配好或者是把网线插好 第一步找到这个 第二步打开网络适配器 选择图中所指位置 设置好之后 开机启动 centos 第三步 开机以后 编写网卡文件保存 重启网卡就可以了&#xff0c;如果重启网卡不管用&#xff0c;则重启虚拟机即可 “ ifcfg-ens160 ” 这…...

AcWing 3708. 求矩阵的鞍点

输入样例&#xff1a; 3 4 1 2 3 4 1 2 3 4 1 2 3 4输出样例&#xff1a; 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 职责&#xff1a; 1.负责web前端架构的搭建&#xff0c;核心业务功能开发和核心代码编写。 2.配合产品经理&#xff0c;实现产品UI和交互方面的需求&#xff0c;持续界面优化&#xff0c;提升用户体验。 3.参与相关业务需求变更评审。 4.…...

从源程序到可执行文件的四个过程

从源程序到可执行文件的四个过程 预处理编译汇编链接 程序要运行起来&#xff0c;必须要经过四个步骤&#xff1a;预处理、编译、汇编和链接&#xff0c;如下图所示&#xff1a; -E选项&#xff1a;提示编译器执行完预处理就停下来&#xff0c;后边的编译、汇编、链接就先不执…...

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下载可能比较慢&#xff0c;选择 下载有问题&…...

Redis学习路线(9)—— Redis的场景使用

默认做好了其它的前提&#xff0c;只专注于Redis使用 一、短信登录 在没有Redis数据库时&#xff0c;我们会基于Session实现登录&#xff08;利用令牌进行授权&#xff09;&#xff0c;是怎么实现的呢&#xff1f; &#xff08;一&#xff09;基于Session的短信登录功能 1、…...

糟了,数据库主从延迟了!

前言 在实际的生产环境中&#xff0c;由单台MySQL作为独立的数据库是完全不能满足实际需求的&#xff0c;无论是在安全性&#xff0c;高可用性以及高并发等各个方面 因此&#xff0c;一般来说都是通过集群主从复制&#xff08;Master-Slave&#xff09;的方式来同步数据&…...

VUE,子组件给父组件传递参数,props 自定义属性,ref

<template><div><!-- 子传父 --><!-- 通过父组件给子组件传递函数类型的props实现&#xff1a;子给父传递数据 --><AA :getAAname"getAAname"/><h1>AA&#xff1a;{{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官网&#xff1a;MySQLhttps://www.mysql.com/ 下载社区版&#xff08;免费&#xff0c;但不提供技术支持&#xff09; 简单说明一下rpm和tar包的区别&#xff1a; tar 只是一种压缩文件格式&#xff0c;所以&#xff0c;它只是把文件压缩打包 rpm&#xf…...

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库&#xff0c;最近一直蠢蠢欲动想要试一下这个库 所以就下载了源码并进行了编译&#xff08;过程比较简单&#xff0c;有文档的&#xff09; 然后在VS2022中引入了Boost环境&#xf…...

【更新公告】Airtest更新至1.3.0.1版本

1. 前言 本次更新为Airtest库更新&#xff0c;版本提升至1.3.0.1版本&#xff0c;主要新增了一些iOS设备相关的装包等接口&#xff0c;以及封装了一些tidevice常用接口。更多更新详情&#xff0c;详见我们下文的描述。 2. 新增iOS设备接口 1&#xff09;iOS安装接口&#xf…...

LLM、Agent与Multi-Agent全面对比:优势、劣势与应用场景分析

引言大语言模型&#xff08;Large Language Model&#xff0c;LLM&#xff09;的出现&#xff0c;让机器具备了前所未有的语言理解和生成能力。然而&#xff0c;单纯的LLM就像一个博学但困在图书馆里的学者——它能回答问题、撰写文章&#xff0c;却无法主动采取行动。于是&…...

Firefox渗透测试插件工作流:15款高价值安全工具实战指南

1. 这不是普通浏览器插件推荐&#xff0c;而是一套可落地的渗透测试辅助工作流 “火狐插件”四个字在安全从业者耳中&#xff0c;常被默认为“轻量级、临时性、辅助性”的代名词——很多人装完Hackbar就以为自己有了渗透入口&#xff0c;点开FoxyProxy调个代理就当完成了环境隔…...

如何快速掌握CircuitJS1桌面版的3个核心秘诀

如何快速掌握CircuitJS1桌面版的3个核心秘诀 【免费下载链接】circuitjs1 Standalone (offline) version of the Circuit Simulator with small modifications based on modified NW.js. 项目地址: https://gitcode.com/gh_mirrors/circ/circuitjs1 CircuitJS1 Desktop …...

Windows系统下Opensmile 3.0保姆级安装配置指南(含PATH环境变量设置与常见错误排查)

Windows系统下Opensmile 3.0保姆级安装配置指南&#xff08;含PATH环境变量设置与常见错误排查&#xff09; 引言 当你第一次接触语音特征提取工具时&#xff0c;Opensmile无疑是一个强大而友好的选择。作为一款开源的音频分析工具&#xff0c;它广泛应用于情感计算、语音识别等…...

终极指南:如何快速构建中文手写识别AI系统(免费数据集)

终极指南&#xff1a;如何快速构建中文手写识别AI系统&#xff08;免费数据集&#xff09; 【免费下载链接】Traditional-Chinese-Handwriting-Dataset Open source traditional chinese handwriting dataset. 项目地址: https://gitcode.com/gh_mirrors/tr/Traditional-Chin…...

STM32G474RB用CMSIS-DAP下载程序,遇到一堆content mismatch错误?别急着换芯片,先检查这个硬件细节

STM32G474RB用CMSIS-DAP下载程序遇到content mismatch&#xff1f;可能是多设备干扰惹的祸 当你在实验室同时调试多块STM32开发板时&#xff0c;是否遇到过这样的场景&#xff1a;昨天还能正常烧录的STM32G474RB板卡&#xff0c;今天突然开始报出一连串content mismatch错误&am…...

GoogleTranslate_IPFinder高级功能详解:自定义IP段扫描与在线同步服务

GoogleTranslate_IPFinder高级功能详解&#xff1a;自定义IP段扫描与在线同步服务 【免费下载链接】GoogleTranslate_IPFinder 谷歌翻译API服务器的IP扫描、测速工具。 项目地址: https://gitcode.com/gh_mirrors/go/GoogleTranslate_IPFinder GoogleTranslate_IPFinder…...

软件测试的隐藏晋升通道:从QA到QE再到QP

在软件测试领域&#xff0c;大多数人熟悉的职业路径是纵向的&#xff1a;初级、高级、测试架构师或测试经理。然而&#xff0c;在喧闹的晋升阶梯背后&#xff0c;还隐藏着一条认知门槛更高、价值密度更大的水平进化通道——从QA到QE&#xff0c;最终抵达QP。这不是岗位名称的更…...

OpenClaw 微信接入指南:从安装到绑定,一步到位

下载地址&#xff1a;OpenClaw Windows 一键部署包 https://xiake.yun/api/download/package/16?promoCodeIV9D9D5198DC OpenClaw 绑定微信教程 1&#xff1a;软件下载完成界面 2&#xff1a;选择右上角设置 3&#xff1a;选择聊天配置 4&#xff1a;选择右边展开&#xff…...

在Python项目中快速接入Taotoken多模型API的完整步骤指南

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 在Python项目中快速接入Taotoken多模型API的完整步骤指南 对于希望将大模型能力集成到Python应用中的开发者而言&#xff0c;直接对…...