Java【多线程】阻塞队列

目录

阻塞队列

阻塞队列是什么?

生产者消费者模型

生产者消费者模型的两个重要优势

1.解耦合(不一定是两个线程之间,也可以是两个服务器之间)

2.阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力(削峰填谷)

标准库中的阻塞队列

生产者消费者模型

阻塞队列实现


阻塞队列

阻塞队列是什么?

阻塞队列是一种特殊的队列

也遵循“先进先出”的原则

阻塞队列是一种线程安全的数据结构,并具有以下特性

1.队列为空,尝试出队列,出队列操作就会阻塞,阻塞到其他线程添加元素为止

2.队列为满,尝试入队列,入队列操作就会阻塞,阻塞到其他线程取走元素为止


生产者消费者模型

生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合

生产者和消费者彼此之间不直接通讯,而是通过阻塞队列来进行通讯


生产者消费者模型的两个重要优势
1.解耦合(不一定是两个线程之间,也可以是两个服务器之间)

a和b不再直接交互了

a的代码中看不见b

b的代码也看不见a

a的代码中和b的代码中只能看到队列

2.阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力(削峰填谷)

理解成服务器收到的请求量的曲线图

b这边可以不关心数据量多少按照自己的节奏慢慢处理队列中的请求数据即可

趁着峰值过去任然继续消费数据

利用波谷的时间来赶紧消费之前积压的数据

三峡大坝起到的效果同样是削峰填谷


生产者消费者模型付出的代价

1.引入队列后,整体的结构会更复杂

此时需要更多的机器进行部署,生产环境的结构会更复杂,管理起来更麻烦

2.效率会有影响


标准库中的阻塞队列

Java标准库中,提供了现成的阻塞队列

BlockingQueue 是一个接口,真正实现的类是LinkedBlockingQueue

put方法用于阻塞式的入队列,take用于阻塞式的出队列

BlockingQueue也有offer,poll,peek等方法,但是则这些方法不带有阻塞特性

put和take才带有阻塞功能

BlockingQueue<String> queue = new LinkedBlockingQueue<>();
queue.put("abc");//入队列
String elem = queue.take();//出队列,如果没有put直接take,就会阻塞
//容量,最大能容纳多少元素
BlockingQueue<String> queue = new LinkedBlockingQueue<>(100);

如果不设置capacity,默认是一个非常大的数值


生产者消费者模型
public static void main(String[] args) throws InterruptedException {BlockingQueue<Integer> blockingQueue = new LinkedBlockingQueue<>();Thread customer = new Thread(()->{while (true){try{int value = blockingQueue.take();System.out.println("消费元素"+value);} catch (InterruptedException e) {throw new RuntimeException(e);}}},"消费者");Thread producer = new Thread(()->{Random random = new Random();while (true){try{int num = random.nextInt(1000);System.out.println("生产元素"+num);Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}},"生产者");producer.start();customer.join();producer.join();}

阻塞队列实现

通过“循环队列”的方式来实现

使用synchronized进行加锁控制

put插入元素的时候判定如果队列满了就进行wait(注意,要在循环中进行wait,被唤醒时不一定队列就不满了,因为同时可能是唤醒了多个线程)

take取出的时候,判定如果队列为空就进行wait(也是循环wait)

class MyBlockingQueue{private String[] data = null;private int head = 0;private int tail = 0;private int size = 0;public MyBlockingQueue(int capacity) {data = new String[capacity];}public void put(String elem) throws InterruptedException {synchronized (this){//此处最好使用while//否则notifyAll的时候,该线程从wait中被唤醒//但是紧接者并未抢占到锁,当锁被抢占的时候,可能又已经队列满了//就只能继续等待while (size >= data.length){//队列满了,需要阻塞//return;this.wait();}data[tail] = elem;tail++;if(tail >= data.length){tail = 0;}size++;this.notify();}}public String take() throws InterruptedException {synchronized (this){while (size == 0){//队列空了,需要阻塞//return null;this.wait();}String ret = data[head];head++;if(head>= data.length){head = 0;}size--;this.notify();return ret;}}
}

 

这里的wait是用来确保接下来的操作是有意义的

wait不一定只是被notify唤醒,还可能被Interrupt这样的方法给中断

如果使用if作为wait的判定条件

此时就存在wait被提前唤醒的风险

这里的循环的目的是为了“二次验证”

判定当前这里的条件是否成立

wait之前先判定一次

wait唤醒也判定一次(再确认一下,队列是否不空)

wait设计的时候本身就是搭配while用的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/57234.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Web前端概述】

HTML 是用来描述网页的一种语言&#xff0c;全称是 Hyper-Text Markup Language&#xff0c;即超文本标记语言。我们浏览网页时看到的文字、按钮、图片、视频等元素&#xff0c;它们都是通过 HTML 书写并通过浏览器来呈现的。 一、HTML简史 1991年10月&#xff1a;一个非正式…

深度学习(一)基础:神经网络、训练过程与激活函数(1/10)

深度学习基础&#xff1a;神经网络、训练过程与激活函数 引言&#xff1a; 深度学习作为机器学习的一个子领域&#xff0c;近年来在人工智能的发展中扮演了举足轻重的角色。它通过模仿人脑的神经网络结构&#xff0c;使得计算机能够从数据中学习复杂的模式和特征&#xff0c;…

当小程序学会‘读心术’:表单处理的神秘法则

哈喽&#xff0c;我是阿佑&#xff0c;今天将给大家给咱们的小程序赋能——“读心术”&#xff01; 文章目录 微信小程序的表单处理表单元素&#xff1a;小程序的“语言”表单事件&#xff1a;小程序的“听觉”表单提交&#xff1a;小程序的“表达”总结 微信小程序的表单处理 …

1 -《本地部署开源大模型》如何选择合适的硬件配置

如何选择合适的硬件配置 为了在本地有效部署和使用开源大模型&#xff0c;深入理解硬件与软件的需求至关重要。在硬件需求方面&#xff0c;关键是配置一台或多台高性能的个人计算机系统或租用配备了先进GPU的在线服务器&#xff0c;确保有足够的内存和存储空间来处理大数据和复…

设置了超时时间但是不起作用,浏览器里的setTimeout有 bug?

你可能也遇到过这样的问题:写个setTimeout定时器,结果时间一长,浏览器就开始捣乱。比如你想要设置一个几小时甚至几天的延时,突然发现浏览器不听话了!这时候你就会想,难道浏览器的定时器是有上限的?没错,你没看错,setTimeout其实有个最大值限制,时间一超过这个值,就…

Python Numpy 实现神经网络自动训练:反向传播与激活函数的应用详解

Python Numpy 实现神经网络自动训练&#xff1a;反向传播与激活函数的应用详解 这篇文章介绍了如何使用 Python 的 Numpy 库来实现神经网络的自动训练&#xff0c;重点展示了反向传播算法和激活函数的应用。反向传播是神经网络训练的核心&#xff0c;能够通过计算梯度来优化模…

嵌入式入门学习——7Protues导入Arduino IDE生成的固件和Arduino使用库文件开发

0 系列文章入口 嵌入式入门学习——0快速入门&#xff0c;Let‘s Do It&#xff01; 1 Arduino IDE 请自行下载安装&#xff0c;点击标题链接即可&#xff0c;下载完成后 1新建工程并保存&#xff0c;注意工程名和工程所在的文件夹必须同名。 2新建工程的时候注意选择板子型…

循环移位的学习

循环移位&#xff08;Rotational Shift&#xff09;&#xff0c;也称为循环位移&#xff0c;是一种特殊的位移操作。在循环移位中&#xff0c;移出的位会被重新放入到另一端&#xff0c;从而实现循环效果。与逻辑移位和算术移位不同&#xff0c;循环移位不丢失任何位&#xff0…

php中的错误和异常捕获

目录 一&#xff1a; 异常&#xff08;Exceptions&#xff09; 二&#xff1a; 错误&#xff08;Errors&#xff09; 三&#xff1a;实际项目的异常和错误处理 在PHP中&#xff0c;异常&#xff08;Exceptions&#xff09;和错误&#xff08;Errors&#xff09;是两个不同的…

比亚迪车机安装第三方应用教程

比亚迪车机安装第三方应用教程 比亚迪车机U盘安装APP&#xff0c; 无论是dlink3.0还是4.0都是安卓系统&#xff0c;因此理论上安卓应用是都可以安装的&#xff0c;主要就是横屏和竖屏的区别。在比亚迪上安装软件我主要推荐两种方法。 第一种&#xff0c;直接从电脑端下载安装布…

Standard IO

为了提高可移植性&#xff0c;将通用IO接口经过再封装就形成了标准IO&#xff0c;标准IO不仅适用于Unix环境&#xff0c;也兼容非Unix环境&#xff0c;这也是为什么说我们应该尽可能的使用标准IO&#xff0c;通用IO通过文件描述符fd来与文件交互&#xff0c;为了以示区分&#…

DCGAN的原理(附代码解读)

学习DCGAN之前需要了解一下转置卷积 可以参考学DCGAN对抗网络之前--转置卷积(附代码解读)-CSDN博客 1.DCGAN对于GAN的改进之处 网络架构的优化&#xff1a; DCGAN在生成器和判别器中明确使用了卷积层和卷积转置层&#xff08;也称为反卷积层或分数阶卷积层&#xff09;。这一…

『 Linux 』HTTPS

文章目录 HTTPS协议密钥加密的原因加密方式数据指纹网络通信加密方案及短板CA认证CA证书的细节以及如何保证服务端公钥的安全性和数据完整性 CA认证后对称加密与非对称加密配合使用的安全性中间人的攻击方式 HTTPS协议 HTTPS协议并不是一个独立的协议,其是一种以HTTP协议为基础…

基于SSM的洗浴中心管理系统的设计与实现

文未可获取一份本项目的java源码和数据库参考。 方案设计&#xff08;研究的基本内容&#xff0c;拟解决的基本问题&#xff0c;研究步骤、方法及措施&#xff09;&#xff1a; 研究的基本内容&#xff1a;根据当今社会市场所需&#xff0c;通过对比多家洗浴中心进行深入细致的…

第二十九篇:图解TCP三次握手,看过不会忘,从底层说清楚,TCP系列四

⼀开始&#xff0c;客户端和服务端都处于 CLOSED 状态。先是服务端主动监听某个端⼝&#xff0c;处于 LISTEN 状态。 接下来这部分内容的介绍将影响你能不能彻底理解了TCP的三次握手。 一、划重点&#xff1a;只有服务端启动了端口监听&#xff0c;客户端TCP握手才能建立连接&…

ubuntu系统库和Anaconda库冲突问题

之前安装opencv时没出现过这种问题,自从安装Anaconda后就总遇到问题。记录下自己的解决过程。 目录 第一步 第二步 第三步 安装opencv时出现以下问题: /usr/bin/ld: /lib/x86_64-linux-gnu/libwayland-client.so.0: undefined reference to `ffi_prep_cif@LIBFFI_BASE_7.…

若依框架篇-若依集成 X-File-Storage 框架(实现图片上传阿里云 OSS 服务器)、EasyExcel 框架(实现 Excel 数据批量导入功能)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 实现使用 Excel 文件批量导入 1.1 导入功能的前端具体实现 1.2 导入功能的后端具体实现 1.3 使用 EasyExcel 框架实现 Excel 读、写功能 1.4 将 Easy Excel 集成到…

路径跟踪之导航向量场(二)——三维导航向量场

上一期文章介绍了二维平面下的导航向量场计算方法&#xff0c;本期文章将介绍三维空间中&#xff0c;导航向量场及扩展。 本文主要介绍论文[1]中提出的一种基于导航向量场的航迹跟踪算法。此外&#xff0c;虽然本文以三维航迹为例进行介绍&#xff0c;但该方法可非常方便的拓展…

智能优化算法-生物地理学算法(BBO)(附源码)

目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1.内容介绍 生物地理学优化算法 (Biogeography-Based Optimization, BBO) 是一种基于生物地理学原理的元启发式优化算法&#xff0c;由Dan Simon于2008年提出。BBO通过模拟物种在不同栖息地之间的迁移过程来搜索最优解&…

【JavaEE】——四次挥手,TCP状态转换,滑动窗口,流量控制

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 一&#xff1a;断开连接的本质 二&#xff1a;四次挥手 1&#xff1a;FIN 2&#xff1a;过程梳理 …