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

  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. 高性能队列Disruptor

    背景 Disruptor是英国外汇交易公司LMAX开发的一个高性能队列,研发的初衷是解决内存队列的延迟问题(在性能测试中发现竟然与I/O操作处于同样的数量级).基于Disruptor开发的系统单线程能 ...

  2. 8款支持 C# 语言的 AI 辅助编程神器,高效编程利器!

    前言 在当今这个AI技术日新月异的时代,一股创新的浪潮正席卷着软件开发领域,其中AI辅助编程工具以其独特的魅力脱颖而出,成为了众多开发者不可或缺的得力助手.这些工具不仅能够显著提升开发效率,优化代码质 ...

  3. MOS管耗散功率的计算

    MOS管的功率,一般是指Maximum Power Dissipation--Pd,最大的耗散功率,具体是指MOS元件的容许损失,可从产品的热阻上求得.当Tc=25度时,通过附加最大容许损耗Pd,则变 ...

  4. STM32的SYSTICK 定时器(系统滴答定时器)

    什么是SysTick? 这是一个24位的系统节拍定时器system tick timer,SysTick,具有自动重载和溢出中断功能,所有基于Cortex_M3处理器的微控制器都可以由这个定时器获得一 ...

  5. CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比

    CSnakes 是一个用于在.NET项目中嵌入Python代码的工具,由.NET源生成器和运行时组成,能够实现高效的跨语言调用,Github:https://github.com/tonybalone ...

  6. Android设备基础信息获取 源码修改方式 APK开发

    APK 获取设备信息 头文件 import java.io.BufferedReader; import java.io.File; import java.io.FileFilter; import ...

  7. flutter - [02] 基本语法

    题记部分 一.注释 ///这是一个注释 //这也是个注释 /* 这还是个注释 */ void main(List<String> args) { print ('你好 dart'); } ...

  8. Ubuntu通过VMware虚拟机安装步骤

    1.下载Ubuntu系统镜像 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.这个错误需要BIOS CPU里面设置一下,具体问度娘. 18 ...

  9. vue watch监听路由变化

    vue watch监听路由变化 // 监听 this.$route.path // watch监听非DOM元素的改变 watch:{ '$route.path':function(to,from){ ...

  10. OpnenHarmony 开源鸿蒙北向开发——2.第一个工程HelloWorld

    ​ 一.新建项目 我们打开IDE后,选择新建项目 选择这一个 设置参数 设置完成后选择Finish 项目创建后会自动下载一些东西,不用担心 二.运行 我们先什么都不用管,直接运行 先设置设备,我们这里 ...