一、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. 又来新活了!AI电商搜索,或是下一个90亿美元独角兽?

    图源:https://www.shopencore.ai/ 全新体验,大模型驱动的对话式购物搜索. Encore, 由2024年10月成立的美国初创公司开发.定位于二手商品对话式购物搜索,最终目标为个 ...

  2. DeepSeek模型量化

    技术背景 大语言模型(Large Language Model,LLM),可以通过量化(Quantization)操作来节约内存/显存的使用,并且降低了通讯开销,进而达到加速模型推理的效果.常见的就是 ...

  3. STM32 DMA操作

    https://blog.csdn.net/u014754841/article/details/79525637?utm_medium=distribute.pc_relevant.none-tas ...

  4. SpringBoot实现HandlerInterceptor拦截器的接口没有需要重写的方法也不报错是怎么回事

    以前实现HandlerInterceptor接口,总会提示需要实现3个方法(preHandle.postHandle.afterCompletion).现在没有出现提示.原因:这是Java8的新特性- ...

  5. 使用 Visual Paradigm 的业务流程模型和符号 (BPMN) 综合指南

    业务流程模型和符号 (BPMN) 是一种用于建模和记录业务流程的标准化图形符号.它被广泛采用,因为它能够提供一种清晰.通用的语言,所有利益相关者(业务分析师.技术开发人员和管理人员)都能理解.Visu ...

  6. Ansible - [05] 配置文件详解

    主配置文件 ansible.cfg 修改sudo相关配置,在实际工作中,可能使用ansible时,所使用的用户并不是root用户,而是管理员给的一个普通用户,所以需要考虑ansible相关配置文件需要 ...

  7. FormCreate设计器v5.6发布—AI加持的低代码表单设计器正式上线!

    近期DeepSeek可谓是刷遍全网,当然,在DeepSeek等AI技术的推动下,人工智能正以惊人的速度改变着各行各业.AI不仅是一种技术趋势,更是未来生产力的核心驱动力. 如今,FormCreate设 ...

  8. C语言中标准输出的缓冲机制

    什么是缓冲区 缓存区是内存空间的一部分,再内存中,内存空间会预留一定的存储空间,这些存储空间是用来缓冲输入和输出的数据,预留的这部分空间就叫做缓冲区. 其中缓冲区还会根据对应的是输入设备还是输出设备分 ...

  9. Web前端入门第 13 问:HTML 标签和属性是否区分大小写?

    HELLO,这里是大熊学习前端开发的入门笔记. 本系列笔记基于 windows 系统. 注意:以下截图都来源于 Chrome 浏览器,不同浏览器可能会产生不同的渲染结果. 思考一个问题:英文写法都分大 ...

  10. [Qt 基础-01] QPushButton

    QPushButton 简介 QPushButton是一个很常用的一个按钮控件,主要用于创建一个可按压的按键.它显示了一 个文本和一个图标.另外,你也可以在创建时,指定一个快捷键. 基本用法 1. 创 ...