Java中的阻塞队列--以LinkedBlockingQueue为例
顾名思义,就是一种在对队列进行出队或者入队操作的时候会阻塞的队列。下面使用JDK17中的LinkedBlockingQuece进行简单的介绍。
LinkedBlockingQueue基本结构
LinkedBlockingQueue的主要结构以及构成的数据结构如下图所示。具体来说包括
- 存储元素的链表,first指针指向队头,last指针指向队尾。
- 控制向队列中入队节点的可重入锁 putLock,以及队列满时让生产者线程排队等待的 notFull 条件等待队列。
- 控制向队列中出队节点的可重入锁 takeLock,以及队列为空的时候让消费者排队的 notEmpty 条件等待队列。
- 尝试入队操作的生产者线程。
- 尝试出队操作的消费者线程。

接下来介绍LinkedBlockingQueue的几个基本操作。
入队操作:
- put(E) 将元素入队,如果队列满了那么将操作线程放入等待队列notFull, 直到入队成功。
- offer(E) 将元素入队,如果队列满了那么直接返回false,入队失败。
出队操作:
- take() 将元素出队,如果队列为空那么将操作线程放入等待队列notEmpty,直到出队成功。
- poll() 将元素出队,如果队列为空返回false,出队失败。
put,offer以及 take,poll的操作之间的不同都是在队列不满足条件的时候是将其放入条件等待队列等待队列满足条件的时候唤醒还是直接返回false表示操作失败。
出队入队的基本操作
put(E e)
具体流程如下图所示,这是一个线程安全的队列,因为每次队队列的入队出队操作必须获取锁之后才会继续运行。生产者线程在获取了putLock后判断队列是否还会达到容量,如果还有容量那么直接放入,如果队列已满那么放入notFull等待队列中。因为生产者在队尾操作,消费者在队头操作,不会相互影响,在新增节点的过程中可能会有节点出队。所以在放入元素后判断队列是否还有容量,如果有就将notFull等待队列中的线程唤醒。在释放锁后判断在插入前队列是否为空,如果为空,说明可能有消费者线程在条件等待队列中等待获取元素,那么就去唤醒notEmpty中的线程,这些线程由于之前队列为空被放入条件等待队列等待。

public void put(E e) throws InterruptedException {if (e == null) throw new NullPointerException();final int c;final Node<E> node = new Node<E>(e);final ReentrantLock putLock = this.putLock;final AtomicInteger count = this.count;putLock.lockInterruptibly();try {/** Note that count is used in wait guard even though it is* not protected by lock. This works because count can* only decrease at this point (all other puts are shut* out by lock), and we (or some other waiting put) are* signalled if it ever changes from capacity. Similarly* for all other uses of count in other wait guards.*/while (count.get() == capacity) {notFull.await();}enqueue(node);c = count.getAndIncrement();if (c + 1 < capacity)notFull.signal();} finally {putLock.unlock();}if (c == 0)signalNotEmpty();
}
take()
take操作与put操作类似,只不过操作的锁和等待队列恰好相反。

public E take() throws InterruptedException {final E x;final int c;final AtomicInteger count = this.count;final ReentrantLock takeLock = this.takeLock;takeLock.lockInterruptibly();try {while (count.get() == 0) {notEmpty.await();}x = dequeue();c = count.getAndDecrement();if (c > 1)notEmpty.signal();} finally {takeLock.unlock();}if (c == capacity)signalNotFull();return x;}
另外需要注意的是 使用的两个可重入锁为 非公平锁,也就是说队列中的顺序并不严格满足先进先出的特性。源码的解释也有点冲突。
相关文章:
Java中的阻塞队列--以LinkedBlockingQueue为例
顾名思义,就是一种在对队列进行出队或者入队操作的时候会阻塞的队列。下面使用JDK17中的LinkedBlockingQuece进行简单的介绍。 LinkedBlockingQueue基本结构 LinkedBlockingQueue的主要结构以及构成的数据结构如下图所示。具体来说包括 存储元素的链表࿰…...
16.5万煤气柜柜位计故障分析
一、事故经过: 2015年8月14日20点45分,16.5万立煤气柜柜顶油封溢流口有大量油液溢出,此时雷达柜位计在计算机上示值为63.79米,由于接近傍晚天色较暗,岗位操作员并未及时发现这一异常状况。22点45分左右&…...
高效沟通驱动LabVIEW项目成功
在LabVIEW项目开发中,由于涉及软件、硬件及多方协作,项目沟通效率的高低直接影响开发进度与最终质量。不明确的需求、信息传递中的误解以及跨部门协作的阻碍,常导致项目延误甚至失败。因此,建立高效的沟通机制,确保信息…...
大模型之三十三- 开源Melo 语音合成
大模型之三十三- 开源Melo 语音合成 文本到语音(TTS)系统从基于基础音素的模型演变成复杂的端到端神经方法,这种方法可以直接将文本转换为语音。这一变革得益于深度学习的进步和计算能力的提升,已经在语音的自然度、韵律控制和跨语言能力方面取得了重大进展 。现代TTS系统…...
论文复现:四轮转向车辆后轮转角控制方法研究
写在前面,主要参考以下这篇文章,并复现了其中几种后轮转角控制方法。 一、什么是四轮转向 顾名思义,四轮转向指的是四个轮子都能转向,都能转动。当驾驶员操作方向盘进行前轮转向时,后轮按照特定算法给出的转角跟着转动…...
【UFEN】基于多层特征融合和多任务学习的多模态情感分析
abstract 当前多模态情感分析面临的主要挑战包括:1、模型如何在单一模态中提取情感信息,并实现多模态信息的互补传输;2、在单一模态中体现的情绪与多模态标签不一致的情况下,如何输出相对稳定的预测;3、当单模态信息不…...
uniapp的插件开发发布指南
Hbuilder创建项目 项目根目录创建uni_modules 开发组件 发布到插件市场 填写发布说明(未登录需要登录) 点击提交 在终端可以看到 发布成功! 插件市场查看...
【Linux系统】—— 编译器 gcc/g++ 的使用
【Linux系统】—— 编译器 gcc/g 的使用 1 用 gcc 直接编译2 翻译环境2.1 预处理(进行宏替换)2.2 编译(生成汇编)2.3 汇编(生成机器可识别代码)2.4 链接2.5 记忆小技巧2.6 编译方式2.7 几个问题2.7.1 如何理…...
[微服务]注册中心优化
环境隔离 企业实际开发中,往往会搭建多个运行环境,例如: 开发环境测试环境预发布环境生产环境 这些不同环境之间的服务和数据之间需要隔离。 还有的企业中,会开发多个项目,共享nacos集群。此时,这些项目…...
C++ ——— 模拟实现 vector 类
目录 vector 类的框架 无参数的构造函数 析构函数 获取有效数据个数 获取容量 重载 [] 运算符 可读可写版本 只可读版本 扩容 尾插 实现迭代器 可读可写版本 只可读版本 自定义设置size长度和内容 在任意位置插入 删除任意位置的数据 赋值重载 vector 类的框…...
大华相机DH-IPC-HFW3237M支持的ONVIF协议
使用libONVIF C库。 先发现相机。 配置 lib目录 包含 编译提示缺的文件,到libonvif里面拷贝过来。 改UDP端口 代码 使用msvc 2022的向导生成空项目,从项目的main示例拷贝过来。 CameraOnvif.h #pragma once#include <QObject> #include &l…...
【Java】常用工具类方法:树形结构、获取IP、对象拷贝、File相关、雪花算法等
1、生成子孙树 /*** 生成子孙树** param dataArray 遍历所有数据, 每个数据加到其父节点下* return 子孙树json*/public static JSONArray makeTree(JSONArray dataArray) {List<Map<String, Object>> data new ArrayList<>();for (int i 0; i < dataAr…...
豆瓣电影Top250的数据采集与可视化分析(scrapy+mysql+matplotlib)
文章目录 豆瓣电影Top250的数据采集与可视化分析(scrapy+mysql+matplotlib)写在前面数据采集(Visual Studio Code+Navicat)1.观察网页信息2.编写Scrapy代码(Visual Studio Code)2.1 创建Scrapy项目`doubanProject`2.2 创建爬虫脚本`douban.py`2.3 修改`douban.py`的代码2…...
2024微短剧行业生态洞察报告汇总PDF洞察(附原数据表)
原文链接: https://tecdat.cn/?p39072 本报告合集洞察从多个维度全面解读微短剧行业。在行业发展层面,市场规模与用户规模双增长,创造大量高收入就业岗位并带动产业链升级。内容创作上,精品化、品牌化趋势凸显,题材走…...
PHP语言的数据库交互
PHP语言的数据库交互 引言 在现代Web开发中,数据库是存储和管理应用数据的重要组成部分。随着互联网的快速发展,网站和应用程序对数据存储和操作的需求变得越来越复杂。PHP作为一种广泛使用的服务器端脚本语言,提供了多种数据库交互的方法&…...
flutter跨端UI框架简介
flutter跨端UI框架简介 简介 Flutter是由Google开发的开源应用开发框架,主要用于构建高性能、跨平台的移动、Web和桌面应用程序。Flutter使用Dart语言,提供了一套丰富的Widgets,使开发者能够快速创建美观的用户界面。其最大特点是热重载功能…...
自动化标注平台开源,基于 yolov8标注平台可本地部署
yolov8标注平台本地部署(docker部署),已调通yolov8模型自动预标注功能。 下面开始背景知识…… 1)数据标注为什么在人工智能时代如此重要? 数据标注在人工智能时代如此重要,原因如下: 为机器…...
Walrus Learn to Earn计划正式启动!探索去中心化存储的无限可能
本期 Learn to Earn 活动将带领开发者和区块链爱好者深入探索 Walrus 的技术核心与实际应用,解锁分布式存储的无限可能。参与者不仅能提升技能,还能通过完成任务赢取丰厚奖励!🌊 什么是 Walrus? 数据主权如今正成为越…...
第35天:安全开发-JavaEE应用原生反序列化重写方法链条分析触发类类加载
时间轴: 序列化与反序列化图解: 演示案例: Java-原生使用-序列化&反序列化 Java-安全问题-重写方法&触发方法 Java-安全问题-可控其他类重写方法 Java-原生使用-序列化&反序列化 1.为什么进行序列化和反序列化࿱…...
【mptcp】ubuntu18.04和MT7981搭建mptcp测试环境操作说明
目录 安装ubuntu18.04,可以使用虚拟机安装... 2 点击安装VMware Tool 2 更新ubuntu18.04源... 4 安装ifconfig指令工具包... 5 安装vim工具包... 5...
保姆级教程:在ArcGIS Pro插件中集成你的自定义工具箱(以‘消除重复要素’为例)
从脚本到按钮:ArcGIS Pro插件开发实战指南 在GIS日常工作中,我们常常会遇到一些重复性的数据处理任务。比如数据质检环节的"消除重复要素"操作,虽然可以通过Python脚本实现,但每次都需要打开IDE或Python窗口执行代码&am…...
除了ulimit -c unlimited:深入理解Linux core dump机制与高级配置指南
深入Linux核心转储:从基础配置到生产环境实战指南当服务器上的关键应用突然崩溃时,系统管理员最需要的就是一份完整的"事故现场记录"。Linux的core dump机制正是为此而生,它能保存程序崩溃时的内存状态、寄存器值和调用堆栈&#x…...
Unity安卓构建实战指南:解决APK真机安装闪退与构建失败
1. 这不是一本“从零开始”的书,而是一份你真正上手Unity安卓游戏开发前必须撕开的说明书我带过三届Unity实习工程师,也帮二十多个独立开发者把Demo打包进Google Play。每次看到新人在“安卓构建失败”报错里反复挣扎,或者对着“IL2CPP编译卡…...
AMLP框架实战:基于MACE构建高精度机器学习势函数
1. 项目概述:当机器学习势函数遇上自动化管道在计算化学和材料科学领域,我们长久以来面临着一个核心矛盾:精度与效率的权衡。密度泛函理论(DFT)能提供接近实验的精度,但计算成本高昂,通常只能处…...
C语言双端队列完整实现:一行代码吃透头尾操作,算法效率拉满
一、为什么C语言实现双端队列,是数据结构的必学天花板?在C语言数据结构里,队列、栈都是基础中的基础,但真正能把灵活度、效率、内存管理三者揉到一起的,还得是双端队列(deque)。普通队列只能一头…...
环境光遮蔽(Ambient Occlusion):揭秘那个让虚拟世界“有重量感“的阴影魔法
一、一个让我"开窍"的老木匠故事 我有个朋友是传统家具的修复师,他给我讲过一个让我至今难忘的故事。他说他刚入行时跟着一位 70 多岁的老木匠师父学习——师父让他做的第一件事不是雕花、不是榫卯——而是"看阴影"——这个看似奇怪的训练改变了…...
别再死记硬背SMO公式了!用Python手写一个SVM分类器,带你一步步拆解SMO核心逻辑
用Python手写SVM分类器:代码驱动理解SMO算法核心在机器学习领域,支持向量机(SVM)以其优秀的分类性能和坚实的数学基础著称。然而,许多学习者在理解其核心算法——序列最小优化(SMO)时,往往被复杂的数学推导所困扰。本文将采用一种…...
WPF虚拟桌宠组件:可嵌入、高性能、工程化UI生命体
1. 这不是“桌面宠物”,而是一个可嵌入的WPF UI组件化生命体你可能在Windows XP时代见过那只晃着尾巴、偶尔打哈欠的3D小猫,也可能在Win10系统托盘里点开过一个会眨眼的像素狐狸——但那些是独立进程、是系统级小工具、是“看一眼就关掉”的轻量娱乐。而…...
电容损坏深度诊断,从外观到 ESR精准区分容衰与漏电
在 PCB 故障中,电容损坏占比超 40%,是当之无愧的 “头号杀手”。很多工程师仅靠 “鼓包漏液” 判断电容好坏,殊不知80% 的电容损坏是隐性的—— 外观平整但容值衰减、ESR 升高、轻微漏电,导致供电不稳、系统重启、噪声增大&#x…...
Gofile批量下载自动化工具:5步实现高效文件管理解决方案
Gofile批量下载自动化工具:5步实现高效文件管理解决方案 【免费下载链接】gofile-downloader Download files from https://gofile.io 项目地址: https://gitcode.com/gh_mirrors/go/gofile-downloader 在当今数字化工作环境中,技术团队经常需要从…...
