LinkedBlockingQueue的take方法底层源码
一、LinkedBlockingQueue的take方法底层源码
LinkedBlockingQueue 的 take 方法是其核心方法之一,用于从队列头部移除并返回元素。如果队列为空,调用 take 方法的线程会被阻塞,直到队列中有新元素
1、take 方法的作用
从队列头部移除并返回元素。
如果队列为空,当前线程会被阻塞,直到队列中有新元素。
该方法会返回移除的元素,如果线程被中断,会抛出 InterruptedException。
2、take 方法的源码
以下是 LinkedBlockingQueue 中 take 方法的源码(基于 JDK 17):

3、源码解析
(1)获取锁

takeLock 是 LinkedBlockingQueue 的成员变量,用于控制移除操作的并发访问
lockInterruptibly() 方法会尝试获取锁,如果线程被中断,会抛出 InterruptedException
(2)检查队列是否为空

count 是一个 AtomicInteger,表示当前队列中的元素数量。
如果队列为空(count.get() == 0),当前线程会调用 notEmpty.await() 进入等待状态,直到队列中有新元素。
notEmpty 是一个 Condition 对象,用于实现消费者线程的阻塞和唤醒。
(3)移除元素

- dequeue 方法从队列头部移除节点并返回其元素:

a、head 是队列的虚拟头节点(不存储实际数据),head.next 是实际的第一个节点。
b、将 head 指向下一个节点,并返回原第一个节点的元素。
c、将原第一个节点的 item 置为 null,帮助垃圾回收。
(4)更新元素数量

- 使用 AtomicInteger 的 getAndDecrement 方法将队列元素数量减 1,并返回减 1 之前的值(c)
(5)唤醒其他消费者线程

- 如果移除后队列不为空(c > 1),调用 notEmpty.signal() 唤醒其他可能正在等待的消费者线程。
(6)释放锁

- 在 finally 块中释放锁,确保锁一定会被释放,避免死锁。
(7)唤醒生产者线程

如果移除前队列已满(c == capacity),调用 signalNotFull() 唤醒可能正在等待的生产者线程。
signalNotFull() 的实现:

获取 putLock,然后调用 notFull.signal() 唤醒生产者线程
(8)返回移除的元素

- 返回从队列头部移除的元素。
二、示例流程图
以下是 take 方法的执行流程图:
1、获取 takeLock。
2、检查队列是否为空:
- 如果为空,等待 notEmpty 条件。
3、从队列头部移除节点。
4、更新元素数量。
5、如果队列不为空,唤醒其他消费者线程。
6、释放 takeLock。
7、如果移除前队列已满,唤醒生产者线程。
8、返回移除的元素。
LinkedBlockingQueue的take方法底层源码的更多相关文章
- 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 ...
随机推荐
- Cuckoo Hash
最近在看APSI中,涉及到了一些hash技术(朴素hash,置换hash,布谷鸟hash),Hash 技术是 PSI 协议中优化通信复杂度和计算杂度的重要工具之一,现在系统的认识一下! 更多关于哈希函 ...
- AI编程助手带来的洞察和启发——程序员职业的变革
前言 从chatgpt的横空出世到国内大模型的强势崛起, 从AI只会写诗作画到辅助编程, AI作为新质生产力的重要角色逐渐进入各行各业,为行业带来新的可能性. Cursor.通义灵码这类"A ...
- manim边学边做--局部变换
本次介绍的两个用于变换的动画类:TransformMatchingShapes和TransformMatchingTex. 它们的主要特点是对一组对象或一段文本进行局部变换,适用于复杂的图形或者文本的 ...
- .NET最佳实践:webapi返回IAsyncEnumerable提升性能
什么是IAsyncEnumerable IAsyncEnumerable<T> 是 .NET 中用于表示异步数据流的接口. 它允许你逐个异步地获取数据项,而不是将所有数据一次性加载到内存中 ...
- mac安装nodejs、npm包设置
一.安装nodejs 1.下载自己系统的nodejs,我选择18.20版本 https://nodejs.cn/download/ 二.设置 1.设置镜像源: npm config set regis ...
- RabbitMQ(六)——路由模式
RabbitMQ系列 RabbitMQ(一)--简介 RabbitMQ(二)--模式类型 RabbitMQ(三)--简单模式 RabbitMQ(四)--工作队列模式 RabbitMQ(五)--发布订阅 ...
- KUKA库卡机器人维修
KUKA库卡机器人作为生产线上的核心设备,一旦出现KUKA机械手故障,将直接影响整个生产线的运行效率.及时的库卡机器人维修工作不仅能够迅速恢复机器人的工作状态,减少生产停滞时间,还能通过预防性维护降低 ...
- HTTP - [01] 简介
HTTP本身是不安全的,因为传输的数据未经加密,可能会被窃听或篡改.为了解决这个问题,引入了HTTPS,即在HTTP上加入SSL/TLS协议,为数据传输提供了加密和身份验证. 一.概述 HTTP( ...
- Ansible - [11] Roles
前言 Q1:什么是Roles 在实际生产环境中,会编写大量的playbook文件来实现不同的功能.而且,每个playbook还可能会调用其他文件(变量文件),对于海量的.无规律的文件,管理是个问题.A ...
- NebulaGraph Desktop 使用初体验
前言 前两天 NebulaGraph 官方宣布了全新的开源 Desktop,旨在通过一体化方案解决图数据库部署复杂.工具碎片化.学习成本高等的痛点问题,我也是跃跃欲试.前期在初识 NebulaGrap ...