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

多线程-阻塞队列

目录

阻塞队列

消息队列

阻塞队列用于生产者消费者模型

概念

实现原理

生产者消费者主要优势

缺陷

阻塞队列的实现

1.写一个普通队列

2.加上线程安全和阻塞等待

3.解决代码中的问题


阻塞队列

阻塞队列,是带有线程安全功能的队列,拥有队列先进先出的特性,并带有阻塞功能。

队列为空,尝试出队列,出队操作就会阻塞,一直阻塞到不为空为止。

队列为满,尝试入队列,入队操作也会阻塞,一直阻塞到队列不满为止。

 过程如下:

消息队列

消息队列的先进先出不是普通的先进先出,而是把topic这样的数据结构作为参数对数据进行分类,而在出对列的时候,指定topic ,每个topic下的数据是先进先出的。消息队列一般也带有阻塞功能。消息队列能够起到的作用是实现"生产者消费者模型",消息队列这种数据结构,在实际开发中经常会被封装成单独的服务器程序,单独部署,这样的服务器程序也被称为消息队列。

阻塞队列用于生产者消费者模型

概念

生产者-消费者模式是一种通过缓冲区将生产者和消费者解耦的设计模式。 生产者线程负责生成数据,而消费者线程负责消费数据。 由于生产者和消费者的工作速度可能不同,因此缓冲区的存在使得它们可以独立运行。

实现原理

在一个进程内,直接可以使用阻塞队列实现。在分布式系统中,需要使用单独部署的消息队列服务器,实现生产者消费者模型。

生产者消费者主要优势

1.解耦合

两个程序A,B,让他们互相调用,意味着A代码种就要包含很多关于B相关的逻辑,B的代码中也会包含和A相关的逻辑,彼此之间就有了一定的耦合,一旦A程序做出修改,可能会影响B相关的逻辑,反之亦然,一旦A出现Bug,那么很容易使B受到牵连。在生产者消费者模型中,使用一个消息队列,将A和B解耦合:

站在A的视角,只和消息队列进行交互,站在B的视角,也之和消息队列进行交互。如果对A程序进行修改,不太容易影响到B程序,遇到Bug,对B也没有影响。如果未来引入C,D等,通过消息队列可以直接让A访问C,D,不需要修改A中的任何代码,直接让A从队列里读取数据即可。 

2.削峰填谷

客户端发送的请求个数是没办法提前预知的,当客户端发送大量请求时,就会导致服务器遇到的请求激增,此时服务器内部有些复杂的程序就会消耗大量资源,导致崩溃。服务器每次处理一个请求就会消耗一定的系统资源,如果同一时刻要处理等待请求多了,消耗的总资源数目超出机器能提供的上限,那么就会出现机器卡死的情况。引入消息队列(mq):

 此时,当A段收到一个请求,就会把请求传递给消息队列,通过消息队列把请求传递给B,无论A给队列请求有多块,B都可以按照固有的节奏来处理这些请求,提高系统的可用性。

缺陷

引入阻塞队列实现生产者消费者模型,效率不如直接访问更快,如上图,多了一次A想mq传递请求,多了一次周转,也多了一次网络通信,效率会有所折损,不适合用在响应熟读要求特别高的场景。

阻塞队列的实现

 阻塞队列是线程安全并带有阻塞功能的队列。

1.写一个普通队列

使用数组实现普通的队列,队列的属性包含一个数组,队首下标,队尾下标,元素个数,实现入队和出队操作。

public class QueueBlock {private int[] array;private int head;private int last;private int  size;void put(int elem) {//判断是否满了,队列满进入阻塞状态if(array.length >= size) {return;}array[last] = elem;last++;if(last >= array.length) {last = 0;}size++;}int take() {//判断是否为空,为空时进入 阻塞if(size == 0) {return 0;}int ret = array[head];head++;if(head >= array.length) {head = 0;}size--;return ret;}
}

2.加上线程安全和阻塞等待

当进行关键代码时,需要加锁,防止在多线程情况下,误判队列满或者空。队满进行wait操作阻塞执行,直到进行take操作入队时解除阻塞状态,队空时也进行wait操作阻塞执行,直到进行put操作出队时解除阻塞状态,也就是说,两个方法互相唤醒对方,由于在一个队列中不会存在既是满又是空的情况,,所以调用的两个方法不会同时进入阻塞状态。

 void put(int elem) throws InterruptedException {//判断是否满了,队列满进入阻塞状态//判满时需要加锁,保证数据真实有效synchronized (this) {if(array.length >= size) {wait();//阻塞等待}}array[last] = elem;last++;if(last >= array.length) {last = 0;}size++;this.notify();}int take() throws InterruptedException {//判断是否为空,为空时进入阻塞//判空时需要加锁,保证数据真实有效synchronized (this) {if(size == 0) {wait();}}int ret = array[head];head++;if(head >= array.length) {head = 0;}size--;this.notify();return ret;}

解除阻塞图片描述如下:

3.解决代码中的问题

wait操作不仅仅会被notify唤醒,还有可能被其他操作唤醒,比如interrupt。也就是说,在进行等待操作时,可能被其他操作终止,然后继续向下执行,这时可以使用while循环搭配条件使用,在线程唤醒之后再次对条件进行判断,队列为空/满将再次进行阻塞,等待真正的唤醒操作。于是代码最终改进为:


public class QueueBlock {private int[] array;private int head;private int last;private int  size;void put(int elem) throws InterruptedException {//判断是否满了,队列满进入阻塞状态//判满时需要加锁,保证数据真实有效synchronized (this) {while(array.length >= size) {wait();//阻塞等待}}array[last] = elem;last++;if(last >= array.length) {last = 0;}size++;this.notify();}int take() throws InterruptedException {//判断是否为空,为空时进入阻塞//判空时需要加锁,保证数据真实有效synchronized (this) {while(size == 0) {wait();}}int ret = array[head];head++;if(head >= array.length) {head = 0;}size--;this.notify();return ret;}
}

相关文章:

多线程-阻塞队列

目录 阻塞队列 消息队列 阻塞队列用于生产者消费者模型 概念 实现原理 生产者消费者主要优势 缺陷 阻塞队列的实现 1.写一个普通队列 2.加上线程安全和阻塞等待 3.解决代码中的问题 阻塞队列 阻塞队列,是带有线程安全功能的队列,拥有队列先进…...

el-table合并单元格之后,再进行隔行换色的且覆盖表格行鼠标移入的背景色的实现

el-table 中有现成的隔行换色功能,只要增加 stripe 属性即可。但是如果有单元格合并的话,这个属性就不可用了。这时候我们就需要动点小心思了。 基于相同字段进行合并 单元格合并:基于表头中的某一列,具有相同值的个数相加进行合…...

java模拟键盘实现selenium上下左右键 table中的左右滚动条实现滚动

在这篇文章中,我们将学习如何使用Java编程语言模拟键盘输入,特别是模拟上下左右方向键的操作。这是一个很有趣的项目,尤其适合刚入行的开发者。我们将分步进行,接下来,我们会通过表格展示整个实现过程,然后…...

SDF,一个从1978年运行至今的公共Unix Shell

关于SDF 最近发现了一个很古老的公共Unix Shell服务器,这个项目从1978年运行至今,如果对操作系统,对Unix感兴趣,可以进去玩一玩体验一下 SDF Public Access UNIX System - Free Shell Account and Shell Access 注册方式 我一…...

前馈神经网络 (Feedforward Neural Network, FNN)

代码功能 网络定义: 使用 torch.nn 构建了一个简单的前馈神经网络。 隐藏层使用 ReLU 激活函数,输出层使用 Sigmoid 函数(适用于二分类问题)。 数据生成: 使用经典的 XOR 问题作为数据集。 数据点为二维输入&#xff…...

【Python进阶】Python中的数据库交互:使用SQLite进行本地数据存储

1、数据持久化与访问效率 数据持久化是指程序运行过程中产生的数据能够长期保存,即使程序关闭或系统重启后仍可读取和修改。通过数据库,我们可以确保数据持久化的同时,实现数据的快速访问。例如,银行系统需要实时更新账户余额&am…...

ZooKeeper单机、集群模式搭建教程

单点配置 ZooKeeper在启动的时候,默认会读取/conf/zoo.cfg配置文件,该文件缺失会报错。因此,我们需要在将容器/conf/挂载出来,在制定的目录下,添加zoo.cfg文件。 zoo.cfg logback.xml 配置文件的信息可以从二进制包…...

函数指针示例

目录&#xff1a; 代码&#xff1a; main.c #include <stdio.h> #include <stdlib.h>int Max(int x, int y); int Min(int x, int y);int main(int argc, char**argv) {int x,y;scanf("%d",&x);scanf("%d",&y);int select;printf(&q…...

vue如何实现组件切换

一、使用条件渲染 (v-if) <template><div><button click"currentView ComponentA">Show Component A</button><button click"currentView ComponentB">Show Component B</button><component-a v-if"curren…...

计算机视觉 1-8章 (硕士)

文章目录 零、前言1.先行课程&#xff1a;python、深度学习、数字图像处理2.查文献3.环境安装 第一章&#xff1a;概论1.计算机视觉的概念2.机器学习 第二章&#xff1a;图像处理相关基础1.图像的概念2.图像处理3.滤波器4.卷积神经网络CNN5.图像的多层表示&#xff1a;图像金字…...

整数唯一分解定理

整数唯一分解定理&#xff0c;也称为算术基本定理&#xff0c;是由德国数学家高斯在其著作《算术研究》中首次提出的。本文回顾整数唯一分解定理以及对应的几个重要结论。 一、整数唯一分解定理 整数唯一分解定理&#xff0c;也称为算术基本定理&#xff0c;是数论中的一个重…...

Grass脚本2倍速多账号

前言&#xff0c;小编也是第一次撸空投&#xff0c;我是抱着试一试的态度&#xff0c;梦想总是要有的万一白嫖了呢 Grass 是什么&#xff1f; Grass 扩展程序是一款创新的工具&#xff0c;它可以帮助您释放未使用的网络资源的力量。 通过分享您的剩余带宽&#xff0c;您可以赚…...

15分钟学 Go 第 56 天:架构设计基本原则

第56天&#xff1a;架构设计基本原则 学习目标 理解和掌握基本的架构设计原则&#xff0c;以提升软件系统的可维护性、可扩展性和可重用性。 内容提纲 架构设计原则概述常见架构设计原则 单一职责原则 (SRP)开放/封闭原则 (OCP)里氏替换原则 (LSP)接口分离原则 (ISP)依赖反…...

HTML5 Video(视频)

HTML5 Video(视频) HTML5视频是现代网页设计中不可或缺的一部分,它允许开发者在网页中嵌入视频内容,为用户提供丰富多样的媒体体验。本文将深入探讨HTML5视频的各个方面,包括其基本用法、支持的格式、自定义播放器、浏览器兼容性以及最佳实践。 一、HTML5视频的基本用法 …...

开源模型应用落地-qwen模型小试-Qwen2.5-7B-Instruct-tool usage入门-串行调用多个tools(三)

一、前言 Qwen-Agent 是一个利用开源语言模型Qwen的工具使用、规划和记忆功能的框架。其模块化设计允许开发人员创建具有特定功能的定制代理,为各种应用程序提供了坚实的基础。同时,开发者可以利用 Qwen-Agent 的原子组件构建智能代理,以理解和响应用户查询。 本篇将介绍如何…...

MySQL:表设计

表的设计 从需求中获得类&#xff0c;类对应到数据库中的实体&#xff0c;实体在数据库中表现为一张一张的表&#xff0c;类中的属性就对应着表中的字段&#xff08;也就是表中的列&#xff09; 表设计的三大范式&#xff1a; 在数据库设计中&#xff0c;三大范式&#xff0…...

173. 二叉搜索树迭代器【 力扣(LeetCode) 】

文章目录 零、原题链接一、题目描述二、测试用例三、解题思路四、参考代码 零、原题链接 173. 二叉搜索树迭代器 一、题目描述 实现一个二叉搜索树迭代器类BSTIterator &#xff0c;表示一个按中序遍历二叉搜索树&#xff08;BST&#xff09;的迭代器&#xff1a; BSTIterato…...

大三学生实习面试经历(1)

最近听了一位学长的建议&#xff0c;不能等一切都准备好再去开始&#xff0c;于是就开始了简历投递&#xff0c;恰好简历过了某小厂的初筛&#xff0c;开启了线上面试&#xff0c;记录了一些问题&#xff1a; &#xff08;通过面试也确实了解到了自己在某些方面确实做的还不够…...

【论文复现】STM32设计的物联网智能鱼缸

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀STM32设计的物联网智能鱼缸 【1】项目功能介绍【2】设计需求总结【3】项目硬件模块组成 1.2 设计思路【1】整体设计思路【2】ESP8266工作模式…...

常见长选项和短选项对应表

长选项和短选项的等效形式 在命令行工具中&#xff0c;这种长选项&#xff08;如--delete&#xff09;和短选项&#xff08;如-d&#xff09;等效的情况很常见。例如--verbose和-v&#xff08;用于输出详细信息&#xff09;&#xff0c;--quiet和-q&#xff08;用于安静模式&a…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...