一、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方法底层源码的更多相关文章

  1. Android开发之漫漫长途 Ⅵ——图解Android事件分发机制(深入底层源码)

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  2. 为什么很多类甚者底层源码要implements Serializable ?

    为什么很多类甚者底层源码要implements Serializable ? 在碰到异常类RuntimeException时,发现Throwable实现了 Serializable,还有我们平进的ja ...

  3. List-LinkedList、set集合基础增强底层源码分析

    List-LinkedList 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 继上一章继续讲解,上章内容: List-ArreyLlist集合基础增强底层源码分析:https:// ...

  4. 从底层源码浅析Mybatis的SqlSessionFactory初始化过程

    目录 搭建源码环境 POM依赖 测试SQL Mybatis全局配置文件 UserMapper接口 UserMapper配置 User实体 Main方法 快速进入Debug跟踪 源码分析准备 源码分析 ...

  5. Java泛型底层源码解析-ArrayList,LinkedList,HashSet和HashMap

    声明:以下源代码使用的都是基于JDK1.8_112版本 1. ArrayList源码解析 <1. 集合中存放的依然是对象的引用而不是对象本身,且无法放置原生数据类型,我们需要使用原生数据类型的包 ...

  6. 2018.11.20 Struts2中对结果处理方式分析&struts2内置的方式底层源码剖析

    介绍一下struts2内置帮我们封装好的处理结果方式也就是底层源码分析 这是我们的jar包里面找的位置目录 打开往下拉看到result-type节点 name那一列就是我们的type类型取值 上一篇博 ...

  7. HashMap和ConcurrentHashMap的区别,HashMap的底层源码

    HashMap本质是数组加链表,根据key取得hash值,然后计算出数组下标,如果多个key对应到同一个下标,就用链表串起来,新插入的在前面. ConcurrentHashMap在HashMap的基础 ...

  8. 总结HashSet以及分析部分底层源码

    总结HashSet以及分析部分底层源码 1. HashSet继承的抽象类和实现的接口 继承的抽象类:AbstractSet 实现了Set接口 实现了Cloneable接口 实现了Serializabl ...

  9. LInkedList总结及部分底层源码分析

    LInkedList总结及部分底层源码分析 1. LinkedList的实现与继承关系 继承:AbstractSequentialList 抽象类 实现:List 接口 实现:Deque 接口 实现: ...

  10. Vector总结及部分底层源码分析

    Vector总结及部分底层源码分析 1. Vector继承的抽象类和实现的接口 Vector类实现的接口 List接口:里面定义了List集合的基本接口,Vector进行了实现 RandomAcces ...

随机推荐

  1. MySQL分页性能思考

    MySQL分页性能思考 关键词:深度分页 背景 最近有一个需求:在后台管理页面中,需要展示产品信息的列表. 之前版本开发中产品信息是用户填写完所有字段之后能进行保存.在之前的基础上需要支持用户不完全填 ...

  2. ef 值转换与值比较器

    前言 简单介绍一下,值转换器和值比较器. 正文 为什么有值转换器这东西呢? 那就是这个东西一直必须存在. 比如说,我们的c# enum 对应数据库的什么呢? 是int还是string呢? 一般情况下, ...

  3. Nodejs 实现一个CRC16校验

    近日在开发一个数据平台,据说nodejs比较适合DIRT类型的程序,所以也搞了一把,虽然接收.转发及其报文解析等功能顺利的实现了,但是由于某些报文涉及到应答,故而需要CRC校验,也算是一个小坑吧,故而 ...

  4. 首届超算互联网峰会!天翼云弹性高性能计算E-HPC亮相!

    4月11日,首届超算互联网峰会暨国家超算互联网平台上线仪式在天津顺利举办,来自部委.省级科技厅.中国科学院.中国工程院.计算产业链相关企业等专家.代表数百人共聚一堂,见证了这一历史性时刻.天翼云作为副 ...

  5. 从cos下载文件

    新建test.sh脚本 #!/bin/bash set -e cospath=https://11111.cos.ap-beijing.myqcloud.com/emr/hive/script/202 ...

  6. Luogu P3959 宝藏 题解 [ 紫 ] [ 状压 dp ] [ 二项式定理 ]

    宝藏:一个对着蓝书代码调都能调两个小时的大毒瘤,但是思路还是很值得借鉴的,有普通状压和三进制状压两种做法,或者暴搜剪枝也可以(这里不介绍暴搜剪枝做法). 普通状压做法 观察到 \(n\le 12\), ...

  7. 【FAQ】HarmonyOS SDK 闭源开放能力 —Live View Kit (1)

    1.问题描述: 客户端创建实况窗后,通过Push kit更新实况窗内容,这个过程是自动更新的还是客户端解析push消息数据后填充数据更新?客户端除了接入Push kit和创建实况窗还需要做什么工作? ...

  8. FANUC发那科工业机器人减速器维修小细节

    在现代工业生产中,FANUC发那科机器人已成为不可或缺的一部分.然而,随着时间的推移,发那科机械手减速器可能会出现故障,影响机器人的正常工作. 一.了解减速器的结构与工作原理 在开始FANUC发那科机 ...

  9. 关于企业微信扫码登陆vue

        关于企业微信扫码登陆vue   企业微信扫码登陆官方文档 采用的是第一种(构造独立窗口登录二维码) 对于前端来说就步骤就是 页面展示二维码 => 用户扫码登陆点击确定 => 确定之 ...

  10. Openlayers 距离环绘制

    思路:利用layer的StyleFunction 来使地图移动或者放缩的时候,使圆保持在地图中心 /** * 绘制距离环 * @param {number} distance 每环间隔距离,单位:米 ...