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 ...
随机推荐
- 项目PMP之一项目管理介绍
一.项目定义: 概要:为创造独特的产品.服务或成果而进行的临时性工作 组织创造价值和效益.项目驱动变更创造商业价值的主要方式 特性/要素: 独特的产品.服务或成果,即一个或多个可交付成果(范围.进度( ...
- linux:搭建Drupal
了解 Drupal 是使用 PHP 语言编写的开源内容管理框架(CMF),由内容管理系统(CMS)及 PHP 开发框架(Framework)共同构成.Drupal 具备强大的定制化开发能力,您可使用 ...
- Docker的启停与配置等
Docker测试题 一.选择题(每题5分) 1.关于Docker 安装的表述错误的是(C) A.Docker支持在Windows.Linux.MacOS等系统上安装 B.CentOS安装Docker有 ...
- C语言这种单细胞编程语言和指针的一些理解
转行做嵌入式也有一段时间了,原来做c#以及一些其它的上层语言, 本想的是也就是仅仅是语法上有点不一样.但是实际使用的切身体会真的是只有自己才知道.很多方面刷新了我对c语言以及计算机结构体系的认知 ,绝 ...
- 阻止(禁止)textare回车换行
<van-field v-model="form.messageCont" rows="3" label="口号" autosize ...
- H5调用手机拨打电话的功能
里面加上: 我没有写也是可以的 <meta name="format-detection" content="telephone=yes"/> 该标 ...
- Ubuntu手动安装Mysql包
ubuntu通过tar包安装mysql5.7.21 1.下载解压命令见下: wget https://dev.mysql.com//Downloads/MySQL-5.7/mysql-5.7.21-l ...
- C# 心跳检测实现
原文链接: https://blog.csdn.net/yupu56/article/details/72356700 TCP网络长连接 手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以 ...
- 爱快路由-宽带刷下行流量docker版教程
疑难解答加微信机器人,给它发:进群,会拉你进入八米交流群 机器人微信号:bamibot 简洁版教程访问:https://bbs.8miyun.cn 一天天看直播上行流量太高,给你下行加加速吧,让你下行 ...
- Python异步编程进阶指南:破解高并发系统的七重封印
title: Python异步编程进阶指南:破解高并发系统的七重封印 date: 2025/2/25 updated: 2025/2/25 author: cmdragon excerpt: 本文是异 ...