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

多线程代码案例-阻塞队列

hi,大家好,今天为大家带来多线程案例--阻塞队列

这块知识点也很重要,要好好掌握呀~~~

                                 

🌸🌸🌸🌸🌸🌸🌸🌸🌸🌸🌸🌸🌸🌸🌸🌸🌸🌸🌸🌸🌸🌸🌸🌸🌸🌸🌸🌸🌸

                                             目录

                                💚1.什么是阻塞队列

                                💚2.生产者消费者模型

                                💚3标准库实现阻塞队列

                                💚4.自己实现一个阻塞队列

1.阻塞队列

我们之前在数据结构已经学了队列,什么是队列,我们来回忆一下,队列,是一种数据结构,先进先出.

阻塞队列也如此,先进先出,但是相比队列,它带有阻塞功能,当队列为满,要阻塞等待,当队列为空的时候,要阻塞等待.

因此,阻塞队列是线程安全的数据结构

当队列满的时候,会进入阻塞等待,直到有线程从队列取出元素

当队列空的时候,会进入阻塞等待,直到有线程在队列添加元素

阻塞队列的一个典型应用场景就是 "生产者消费者模型". 这是一种非常典型的开发模型.
需要我们重点掌握
2.生产者消费者模型
生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题
举个简单的例子
包饺子的问题
一家四口人要包饺子
如果每个人擀一个皮,再包一个,这样就太低效了,如何包是最高效率的呢?
爸爸和大女儿作为生产者,(此处是生产饺子皮),包饺子皮,包好放到一个案板上,妈妈和小女儿一起包(此时是消费饺子皮)

 此时这个案板就是相当于一个阻塞队列

当饺子皮放满了,妈妈和小女儿就会告诉爸爸和大女儿先别擀面皮了,那么生产者就可以阻塞等待一会,当案板皮没了,爸爸和大女儿告诉消费者阻塞等待一会

那么这样做提高了线程执行效率

下面来说一说阻塞队列的好处

1.让代码块之间解耦合

啥是耦合呢,就是代码块和代码块之间的关联性的强弱

举个例子,当自己的好朋友生病了,作为好友,我需要去探望,那么如果是不相关的ABCD,那么我可以直接不管,我和我好友的耦合性就很高,相反,我和ABCD耦合性很低

说到这里,顺便说一下啥是内聚

内聚就是功能一样的代码放在一起,再举个例子,衣服要分门别类的放,就是相同的一类的要放在一起

我们写代码,要遵守"高内聚,低耦合"

我们再来举一个计算机的例子

 

 A服务器给B服务器发送请求,B服务器给A响应

服务器处理请求的时候,很耗费硬件资源,包括不限于(CPU,内存,硬盘,带宽)......

所以当某个硬件资源达到瓶颈,服务器就有挂的风险

假设请求量非常多,那么B回应不过来,B服务器很有可能就挂掉了,它俩耦合性就很高,那么A也就挂掉了

所以我们可以采用增加一个阻塞队列的方式

 

这样增加一个阻塞队列,降低了耦合性,B挂,不影响A


2.削峰填谷

1.削峰

还用这个例子,当A的请求很多的时候,会影响B的响应速率吗,答案是不会!

阻塞队列帮A承担了很多请求,让B保证平稳的速率响应请求,这就是削峰的意思

2.填谷:

当A需求猛增以后,迅速进入猛减期,此时会影响B响应速率吗,还是不会!

阻塞队列会自动调节,当 请求量突然骤减,阻塞队列会拿出之前积压的请求分配给B,这就是填谷


说完作用,差不多介绍完了,现在来看一看实现吧

3.标准库实现阻塞队列

采用BlockingQueue

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
//生产者消费者模型public class ThreadDemo3 {public static void main(String[] args) {BlockingQueue<Integer> queue=new LinkedBlockingQueue();//消费者Thread t1=new Thread(()->{while(true){try {int value=queue.take();System.out.println("消费"+value);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t1.start();//生产者Thread t2=new Thread(()->{int value=0;while(true){try {queue.put(value);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("生产"+value);value++;try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t2.start();}
}

标准库实现比较简单,我们自己实现就有难度了

4.自己实现阻塞队列

需要3步

1.实现一个普通队列

2.加上线程安全(加锁) 

3.增加阻塞等待功能

废话不多说,上代码

//自己实现阻塞队列class  MyBlockingQueue{volatile    private int[] items=new int[1000];volatile     private int head=0;volatile    private int tail=0;volatile   private int size=0;//入队列synchronized    public void put(int elem) throws InterruptedException {if(size==items.length){//return;this.wait();}items[tail]=elem;tail++;if(tail==items.length){tail=0;}size++;this.notify();}synchronized   public Integer take() throws InterruptedException {if(size==0){//  return null;this.wait();}int value=items[head];head++;if(head==items.length){head=0;}size--;this.notify();return value;}}public class ThreadDemo2 {public static void main(String[] args) {MyBlockingQueue queue = new MyBlockingQueue();//消费者Thread t1 = new Thread(()->{while (true) {int value = 0;try {value = queue.take();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("消费" + value);}});t1.start();Thread t2=new Thread(()->{int value=0;while(true){try {queue.put(value);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("生产"+value);value++;try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t2.start();System.out.println("hello");}}

 解释:

 当队列满就阻塞等待,取出元素再唤醒,继续执行增加操作(如蓝色线)

 当队列空就阻塞等待,放进元素再唤醒,继续执行取出操作(如红色线)

在put和take方法上加上锁,保证原子性,线程安全

在这个操作中涉及到多次读以及修改操作,为了保证读取到的数据是正确的,也就会为了保证内存可见性,我们采用增加关键字volatile的操作

并且上述不可能同时wait,不可能有一个队列又空又满!!!

这里还有最后一个小问题

为啥要用while,不用if,?

 

看看wait的源码

wait可能会在线程执行过程中被提前唤醒,条件没成熟就醒了,这不符合代码逻辑,所以我们把if改为while,wait操作之前,发现条件不满足wait,等到wait被唤醒以后,再次判断wait唤醒是不是因为满足条件,不满足,就继续等待!!! 

以上就是今天的所有内容了,我们下期再见啦!!!

                    

 

相关文章:

多线程代码案例-阻塞队列

hi,大家好,今天为大家带来多线程案例--阻塞队列 这块知识点也很重要,要好好掌握呀~~~ &#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x…...

mysql的limit查询竟然有坑?

背景 最近项目联调的时候发现了分页查询的一个bug&#xff0c;分页查询总有数据查不出来或者重复查出。 数据库一共14条记录。 如果按照一页10条。那么第一页和第二页的查询SQL和和结果如下。 .png) 那么问题来了&#xff0c;查询第一页和第二页的时候都出现了11,12,13的记录…...

【Docker】MAC电脑下的Docker操作

文章目录安装Docker部署mysql 一主一从登录ChatGPT搞方案本地创建一个文件夹编辑docker-compose.yml文件启动检查并编排容器验证基于command的my.cnf配置的加载主数据库建一个用户给子数据库用于主从复制启动主从同步安装Docker 官网地址 https://www.docker.com/ 下载安装 验…...

【Python3】matplotlib,模块,进/线程,文件/xml,百度人脸api,hal/aiohttp/curl

文章目录1.matplotlib/时间复杂度/线性表&#xff1a;顺序表要求存储空间必须连续2.python模块导入&#xff1a;python3 -c ‘import sys;print(sys.path)’ 显示导入模块时会去哪些路径下查找3.进/线程&#xff1a;进/线程是不能随便创建&#xff0c;就像每招一个员工是有代价…...

异或相关算法

文章目录1. 异或的性质2. 题目一3. 题目二4. 题目三5. 题目四1. 异或的性质 我们知道&#xff0c;异或的定义是&#xff1a;相同为0&#xff0c;相异为1。所以也被称为无进位相加&#xff0c;根据这定义&#xff0c;我们可以得出三个性质&#xff1a; 1. N ^ N0。2. N ^ 0N。3…...

python 使用pyshp读写shp文件

安装 pip install pyshp 引入 import shapefile读取 sfshapefile.Reader("{路径名}",encodingutf-8) # 仅仅读取 shapes与shape shapessf.shapes() 返回值是一个列表&#xff0c;包含该文件中所有的”几何数据”对象shapesf.shape(0) Shape是第1个”几何数据”…...

eNSP FTP基础配置实验

关于本实验在本实验中&#xff0c;我们通过两台路由器来展示通过FTP在两台路由器之间传输文件。其中一台路由器AR2作为FTP服务器&#xff0c;另一台路由器AR1以FTP的方式登录AR2&#xff0c;并对AR2的文件系统进行一些更改。实验目的熟悉华为网络设备文件系统的管理。掌握华为网…...

堆及其多种接口与堆排序的实现

我们本期来讲解堆结构 目录 堆的结构 堆的初始化 堆的销毁 堆的插入 向上调整算法 堆的删除 向下调整算法 取堆顶元素 判断堆是否为空 堆中元素个数 堆排序 向下调整与向上调整效率计算 Top-K问题 全部代码 堆的结构 堆是一种用数组模拟二叉树的结构 逻辑结构是…...

JNI原理及常用方法概述

1.1 JNI(Java Native Interface) 提供一种Java字节码调用C/C的解决方案&#xff0c;JNI描述的是一种技术。 1.2 NDK(Native Development Kit) Android NDK 是一组允许您将 C 或 C&#xff08;“原生代码”&#xff09;嵌入到 Android 应用中的工具&#xff0c;NDK描述的是工具集…...

【Docker】之docker-compose的介绍与命令的使用

&#x1f341;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; 文章目录docker-compose简介docker-compose基础…...

水果新鲜程度检测系统(UI界面+YOLOv5+训练数据集)

摘要&#xff1a;水果新鲜程度检测软件用于检测水果新鲜程度&#xff0c;利用深度学习技术识别腐败或损坏的水果&#xff0c;以辅助挑拣出新鲜水果&#xff0c;支持实时在线检测。本文详细介绍水果新鲜程度检测系统&#xff0c;在介绍算法原理的同时&#xff0c;给出Python的实…...

flask多并发

多线程 flask默认使用多进程处理请求&#xff0c;因此&#xff0c;是支持并发的。比如两个调用a.html和b.html&#xff0c; 请求a.html未运行完成&#xff0c;在浏览访问b.html不会阻塞。开两个不同浏览器&#xff0c;分别请求请求运行时间较长的a.html也不阻塞。只要不用一个…...

我用Python django开发了一个商城系统,已开源,求关注!

起始 2022年我用django开发了一个商城的第三方包&#xff0c;起名为&#xff1a;django-happy-shop。当时纯粹是利用业余时间来开发和维护这个包&#xff0c;想法也比较简单&#xff0c;Python语言做web可能用的人比较少&#xff0c;不一定有多少人去关注&#xff0c;就当是一个…...

大数据项目之数仓相关知识

第1章 数据仓库概念 数据仓库&#xff08;DW&#xff09;: 为企业指定决策&#xff0c;提供数据支持的&#xff0c;帮助企业&#xff0c;改进业务流程&#xff0c;提高产品质量等。 DW的输入数据通常包括&#xff1a;业务数据&#xff0c;用户行为数据和爬虫数据等 ODS: 数据…...

RK3588平台开发系列讲解(视频篇)RTP H264 码流打包详解

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、单 NALU 封包方式二、组合封包方式三、分片封包方式沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 H264 码流是放在 RTP 的有效载荷部分的。因此有效载荷前面的 RTP 头部跟码流本身是没有关系的,所以我…...

realloc的补充 柔性数组

&#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练&#xff0c;题解C&#xff0c;C的使用文章&#xff0c;「初学」C &#x1f525;座右铭&#xff1a;“不要等到什么都没有了&#xff0c;才下…...

【C语言】柔性数组

柔性数组1. 柔性数组介绍2. 柔性数组特点3. 用例3.1 代码一&#xff1a;3.2 代码二&#xff1a;4. 柔性数组优势&#xff1a;1. 柔性数组介绍 也许你从来没有听说过柔性数组&#xff08;flexible array&#xff09;这个概念&#xff0c;但是它确实是存在的。 C99 中&#xff0c…...

【Linux】权限详解

前言首先我们先来看一下权限的概念&#xff1a;在多用户计算机系统的管理中&#xff0c;权限&#xff08;privilege&#xff09;是指某个特定的用户具有特定的系统资源使用权力&#xff0c;像是文件夹&#xff0c;特定系统指令的使用或存储量的限制。通常&#xff0c;系统管理员…...

Android 之 打开相机 打开相册

Android 之 打开系统摄像头拍照 打开系统相册&#xff0c;并展示1&#xff0c;清单文件 AndroidManifest.xml<uses-permission android:name"android.permission.INTERNET" /><!--文件读取权限--><uses-permission android:name"android.permiss…...

C语言数据结构初阶(8)----栈与队列OJ题

CSDN的uu们&#xff0c;大家好。这里是C语言数据结构的第八讲。 目标&#xff1a;前路坎坷&#xff0c;披荆斩棘&#xff0c;扶摇直上。 博客主页&#xff1a; 姬如祎 收录专栏&#xff1a;数据结构与算法栈与队列的知识点我➡➡队列相关点我➡➡栈相关2. 用栈实现队列原题链接…...

JavaScript——原型对象

JavaScript——原型对象专题 文章目录JavaScript——原型对象专题1. 原型对象2. 原型对象的this指向3. 案例4. constructor属性5. 对象原型6. 总结7. 原型继承8. 原型链由先前的学习可知&#xff0c;构造函数实例创建的对象彼此独立、互不影响&#xff0c;很好的体现了面向对象…...

网络安全 2023 年为什么如此吃香?事实原来是这样....

前言由于我国网络安全起步晚&#xff0c;所以现在网络安全工程师十分紧缺。俗话说:没有网络安全就没有国家安全为什么选择网络安全&#xff1f;十四五发展规划建议明确提出建设网络强国&#xff0c;全面加强网络安全保障体系和能力建设&#xff0c;加强网络文明建设&#xff0c…...

(源码篇02)webpack5中的事件调度系统和NormalModuleFactary核心逻辑

1. 书接上回&#xff0c;从 this.factorizeQueue.add(options, callback); 开始 不是很清楚上下文的兄弟&#xff0c;可以去看下我之前写的 &#xff08;源码篇01&#xff09;浅析webpack5中Compiler中重要的hook调用过程。 此文比较干&#xff0c;各位读者开始阅读前&#xf…...

Vue2.x源码:new Vue()做了啥?

vue源码版本vue2.5.2 new Vue()做了啥? new Vue()会执行_init方法&#xff0c;而_init方法在initMixin函数中定义。 src/core/instance/index.js文件中定义了Vue function Vue (options) {this._init(options) }initMixin(Vue) stateMixin(Vue) eventsMixin(Vue) lifecycl…...

WinForm | C# 弹出简易的消息提示框 (仿Android Toast消息提示)

ApeForms Toast消息提示 文章目录ApeForms Toast消息提示前言方法原型及参数释义消息驻留延时消息弹出模式队列模式抢占模式复用模式UI库安装与使用获取示例源码前言 在使用手机的时候经常会见到屏幕的中下方会弹出消息提示框&#xff0c;它就是Toast&#xff0c;以下是百度百…...

1、DRF实战总结:DRF特点、序列化与RESTful API规范

Django这种基于MVC开发模式的传统框架&#xff0c;非常适合开发基于PC的传统网站&#xff0c;因为它同时包括了后端的开发(逻辑层、数据库层) 和前端的开发(如模板语言、样式)。现代网络应用Web APP或大型网站一般是一个后台&#xff0c;然后对应各种客户端(iOS, android, 浏览…...

SIP协议及其简单介绍

SIP协议及其简单介绍概述流程SIP流程两台设备建立会话原理使用场景概述 SIP&#xff08;Session Initiation Protocol&#xff0c;会话初始化协议&#xff09;是一个应用层协议&#xff0c;用于在互联网上创建、修改和终止多媒体会话。SIP是一个客户端/服务器协议&#xff0c;…...

安全防御第四天:防病毒网关

一、恶意软件1.按照传播方式分类&#xff08;1&#xff09;病毒病毒是一种基于硬件和操作系统的程序&#xff0c;具有感染和破坏能力&#xff0c;这与病毒程序的结构有关。病毒攻击的宿主程序是病毒的栖身地&#xff0c;它是病毒传播的目的地&#xff0c;又是下一次感染的出发点…...

Postman接口与压力测试实例

Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。它提供功能强大的 Web API & HTTP 请求调试。 1、环境变量和全局变量设置 环境变量可以使用在以下地方&#xff1a; URLURL paramsHeader valuesform-data/url-encoded valuesRaw body contentHelper fi…...

TCP/IP socket

## TCP Socket 收发缓冲区: 每个socket在linux内核中都有一个发送缓冲区和一个接收缓冲区。 只要对端将数据发送过来&#xff0c;linux内核TCP/IP协议栈就会负责将数据缓存到socket对应的接收缓冲区中&#xff0c;无论是否调用recv。 recv()所做的工作&#xff0c;只是把内核缓…...

wordpress 迅搜/百度推广怎么才能效果好

Python之路【第四篇】&#xff1a;模块 模块&#xff0c;用一砣代码实现了某个功能的代码集合。 类似于函数式编程和面向过程编程&#xff0c;函数式编程则完成一个功能&#xff0c;其他代码用来调用即可&#xff0c;提供了代码的重用性和代码间的耦合。而对于一个复杂的功能来…...

代做苹果证书网站/360网站安全检测

写 Python 代码最好的方式莫过于使用集成开发环境&#xff08;IDE&#xff09;了。它们不仅能使你的工作更加简单、更具逻辑性&#xff0c;还能够提升编程体验和效率。关于IDE更多的介绍这里就不多做赘述&#xff0c;不太清楚的小伙伴可以baidu一下&#xff01; 初级开发者往往…...

asp网站开发教程/网页

作者介绍 郑泰森 某共享平台集团风控负责人&#xff1b; “数据人创作者联盟”成员。 接&#xff1a;【干货】风控模型如何嵌入策略&#xff08;一&#xff09; 01 三种常见的风险定价方式 我来简单介绍一下三种常见的风险定价方式&#xff0c;刚才介绍的是整体的情况。风险…...

做首饰网站/移动慧生活app下载

关键词&#xff1a;电网络&#xff1b;传递函数&#xff1b;频域模型系统的数学模型是该系统在信号传递过程中的动态特性的数学描述。它是舍弃了各种系统具体特点而抽象出来的共同性质&#xff0c;从而成为研究系统的工具。建立描述控制系统运动特性的数学模型&#xff0c;…...

网站整体结构/深圳网络营销推广培训

文章目录inv穆尔-彭罗斯广义逆pinv对于两个方阵A,BA,BA,B&#xff0c;若ABEABEABE&#xff0c;且EEE为单位阵&#xff0c;则A,BA,BA,B互逆&#xff0c;可记作AB−1,BA−1AB^{-1}, BA^{-1}AB−1,BA−1。 inv 在numpy和scipy中&#xff0c;均提供了求逆函数&#xff0c;分别是n…...

做网站推广托管费用/网站域名查询地址

0x70 - 0x7F 条件跳转&#xff0c;后跟一个字节立即数的偏移(有符号)&#xff0c;共两个字节。如果条件成立&#xff0c;跳转到 当前指令地址 当前指令长度 lb。最大值&#xff1a;向前跳7F&#xff0c;向后跳80。 硬编码汇编0x70JO0x71JNO0x72JB/JNAE/JC0x73JNB/JAE/JNC0x7…...