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 ...
随机推荐
- 基于同态加密的PSI开源库-1
下面介绍一个PSI的开源库,还原论文:CCS2017:Fast Private Set Intersection from Homomorphic Encryption和CCS2018:Labeled ...
- LinkedList可以同时作为堆栈和队列使用
Java里的LinkedList可以同时作为堆栈和队列使用,因此在使用的时候总是会弄混他们的方法,此文就简单总结一下作为不同数据结构使用时的用法. 作为队列 方法 声明 任意两种方法: 一是直接声 ...
- 0515-BufferedInputStream缓存输入输出流
package A10_IOStream; import java.io.*; /* 作为IO流的入门,今天我们见识一些更强大的流.比如能够高效读写的缓冲流,能够转换编码的转换流,能够持久化存储对象的 ...
- 一种把dump里连续的内存保存到文件的方法
前几天调试一个崩溃,截到一个full dump文件,显示一个视频帧数据转换有问题.从调用栈可以看到完整的帧数据. 然后我就想把这个数据保存下来,再构造崩溃场景,VS没有提供把内存dump为文件的功能. ...
- 探索AI,拥抱未来,欢迎加入魔乐世界!
近日,2024开放原子开源生态大会在北京亦庄开幕,大会以"开源赋能产业,生态共筑未来"为主题,来自政府.企业.学术界.研究机构的专家学者汇聚一堂,共同探讨开源在人工智能领域的创新应 ...
- Java虚拟线程探索
在Java 21中,引入了虚拟线程,这是一个非常非常重要的特性,之前一直苦苦寻找的Java协程,终于问世了.在高并发以及IO密集型的应用中,虚拟线程能极大的提高应用的性能和吞吐量. ## 什么是虚拟线 ...
- 单机stome安装
先安装zookeeper,参考本文件夹下安装文档 启动zookeeper 1.解压stome /opt/Server目录下 tar -zxf apache-storm-1.1.0.tar.gz 2.修 ...
- IDEA Spring Boot项目,排查解决maven包冲突
一.Idea安装插件 下载方式1:插件名称:maven helper 打开Idea设置,搜索安装该插件 下载方式2:https://plugins.jetbrains.com/plugin/7179- ...
- C#如何MeasureString、Graphics获取字符串的像素长度
1. 当单元格展示的字符串需要自动换行的时候,使用GDI绘制文本信息,需要计算字符串文本的实际高度信息(需要固定宽度) 方法一:代码如下,会出现文本没有挤满当前行,但是文本实际高度已换行. priva ...
- ABB机器人IO板DSQC651维修检查方法
ABB机器人作为工业自动化的重要设备,其稳定性和可靠性对于生产线的持续运行至关重要.然而,在实际使用中,由于各种原因,可能会出现ABB机器人IO板DSQC651故障,影响机器人的正常运行. 一.ABB ...