LinkedBlockingQueue的put方法底层源码
一、LinkedBlockingQueue的put方法底层源码
LinkedBlockingQueue 的 put 方法是其核心方法之一,用于将元素插入队列。如果队列已满,调用 put 方法的线程会被阻塞,直到队列有空闲空间
1、put 方法的作用
将元素插入队列尾部。
如果队列已满,当前线程会被阻塞,直到队列有空闲空间。
该方法不会返回任何值,也不会抛出异常(除非线程被中断)。
2、put 方法的作用
以下是 LinkedBlockingQueue 中 put 方法的源码(基于 JDK 17):

3、源码解析
(1)参数检查

- LinkedBlockingQueue 不允许插入 null 元素,如果传入 null,会抛出 NullPointerException。
(2)创建新节点

- 将元素封装为一个 Node 节点,Node 是 LinkedBlockingQueue 的内部静态类,用于存储队列中的元素
(3)获取锁

putLock 是 LinkedBlockingQueue 的成员变量,用于控制插入操作的并发访问。
lockInterruptibly() 方法会尝试获取锁,如果线程被中断,会抛出 InterruptedException。
(4)检查队列是否已满

count 是一个 AtomicInteger,表示当前队列中的元素数量。
如果队列已满(count.get() == capacity),当前线程会调用 notFull.await() 进入等待状态,直到队列有空闲空间。
notFull 是一个 Condition 对象,用于实现生产者线程的阻塞和唤醒。
(5)插入元素

- enqueue 方法将新节点插入队列尾部:

last 是队列的尾节点,last.next = node 将新节点链接到队列尾部。
然后更新 last 指向新节点。
(6)更新元素数量

- 使用 AtomicInteger 的 getAndIncrement 方法将队列元素数量加 1,并返回加 1 之前的值(c)
(7)唤醒其他生产者线程

- 如果插入后队列未满(c + 1 < capacity),调用 notFull.signal() 唤醒其他可能正在等待的生产者线程
(8)释放锁

- 在 finally 块中释放锁,确保锁一定会被释放,避免死锁
(9)唤醒消费者线程

如果队列中有一条数据(c == 0),调用 signalNotEmpty() 唤醒可能正在等待的消费者线程。
signalNotEmpty() 的实现:

获取 takeLock,然后调用 notEmpty.signal() 唤醒消费者线程
二、示例流程图
以下是 put 方法的执行流程图:
1、检查元素是否为 null。
2、创建新节点。
3、获取 putLock。
4、检查队列是否已满:
- 如果满,等待 notFull 条件
5、将节点插入队列尾部。
6、更新元素数量。
7、如果队列未满,唤醒其他生产者线程。
8、释放 putLock。
9、如果队列中有一条数据,唤醒消费者线程。
LinkedBlockingQueue的put方法底层源码的更多相关文章
- Android开发之漫漫长途 Ⅵ——图解Android事件分发机制(深入底层源码)
该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...
- 为什么很多类甚者底层源码要implements Serializable ?
为什么很多类甚者底层源码要implements Serializable ? 在碰到异常类RuntimeException时,发现Throwable实现了 Serializable,还有我们平进的ja ...
- List-LinkedList、set集合基础增强底层源码分析
List-LinkedList 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 继上一章继续讲解,上章内容: List-ArreyLlist集合基础增强底层源码分析:https:// ...
- 从底层源码浅析Mybatis的SqlSessionFactory初始化过程
目录 搭建源码环境 POM依赖 测试SQL Mybatis全局配置文件 UserMapper接口 UserMapper配置 User实体 Main方法 快速进入Debug跟踪 源码分析准备 源码分析 ...
- Java泛型底层源码解析-ArrayList,LinkedList,HashSet和HashMap
声明:以下源代码使用的都是基于JDK1.8_112版本 1. ArrayList源码解析 <1. 集合中存放的依然是对象的引用而不是对象本身,且无法放置原生数据类型,我们需要使用原生数据类型的包 ...
- 2018.11.20 Struts2中对结果处理方式分析&struts2内置的方式底层源码剖析
介绍一下struts2内置帮我们封装好的处理结果方式也就是底层源码分析 这是我们的jar包里面找的位置目录 打开往下拉看到result-type节点 name那一列就是我们的type类型取值 上一篇博 ...
- HashMap和ConcurrentHashMap的区别,HashMap的底层源码
HashMap本质是数组加链表,根据key取得hash值,然后计算出数组下标,如果多个key对应到同一个下标,就用链表串起来,新插入的在前面. ConcurrentHashMap在HashMap的基础 ...
- 总结HashSet以及分析部分底层源码
总结HashSet以及分析部分底层源码 1. HashSet继承的抽象类和实现的接口 继承的抽象类:AbstractSet 实现了Set接口 实现了Cloneable接口 实现了Serializabl ...
- LInkedList总结及部分底层源码分析
LInkedList总结及部分底层源码分析 1. LinkedList的实现与继承关系 继承:AbstractSequentialList 抽象类 实现:List 接口 实现:Deque 接口 实现: ...
- Vector总结及部分底层源码分析
Vector总结及部分底层源码分析 1. Vector继承的抽象类和实现的接口 Vector类实现的接口 List接口:里面定义了List集合的基本接口,Vector进行了实现 RandomAcces ...
随机推荐
- 高性能队列Disruptor
背景 Disruptor是英国外汇交易公司LMAX开发的一个高性能队列,研发的初衷是解决内存队列的延迟问题(在性能测试中发现竟然与I/O操作处于同样的数量级).基于Disruptor开发的系统单线程能 ...
- 8款支持 C# 语言的 AI 辅助编程神器,高效编程利器!
前言 在当今这个AI技术日新月异的时代,一股创新的浪潮正席卷着软件开发领域,其中AI辅助编程工具以其独特的魅力脱颖而出,成为了众多开发者不可或缺的得力助手.这些工具不仅能够显著提升开发效率,优化代码质 ...
- MOS管耗散功率的计算
MOS管的功率,一般是指Maximum Power Dissipation--Pd,最大的耗散功率,具体是指MOS元件的容许损失,可从产品的热阻上求得.当Tc=25度时,通过附加最大容许损耗Pd,则变 ...
- STM32的SYSTICK 定时器(系统滴答定时器)
什么是SysTick? 这是一个24位的系统节拍定时器system tick timer,SysTick,具有自动重载和溢出中断功能,所有基于Cortex_M3处理器的微控制器都可以由这个定时器获得一 ...
- CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
CSnakes 是一个用于在.NET项目中嵌入Python代码的工具,由.NET源生成器和运行时组成,能够实现高效的跨语言调用,Github:https://github.com/tonybalone ...
- Android设备基础信息获取 源码修改方式 APK开发
APK 获取设备信息 头文件 import java.io.BufferedReader; import java.io.File; import java.io.FileFilter; import ...
- flutter - [02] 基本语法
题记部分 一.注释 ///这是一个注释 //这也是个注释 /* 这还是个注释 */ void main(List<String> args) { print ('你好 dart'); } ...
- Ubuntu通过VMware虚拟机安装步骤
1.下载Ubuntu系统镜像 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.这个错误需要BIOS CPU里面设置一下,具体问度娘. 18 ...
- vue watch监听路由变化
vue watch监听路由变化 // 监听 this.$route.path // watch监听非DOM元素的改变 watch:{ '$route.path':function(to,from){ ...
- OpnenHarmony 开源鸿蒙北向开发——2.第一个工程HelloWorld
一.新建项目 我们打开IDE后,选择新建项目 选择这一个 设置参数 设置完成后选择Finish 项目创建后会自动下载一些东西,不用担心 二.运行 我们先什么都不用管,直接运行 先设置设备,我们这里 ...