一、ArrayBlockingQueue的put方法底层原理

ArrayBlockingQueue 是 Java 并发包 (java.util.concurrent) 中的一个基于数组实现的有界阻塞队列。它的 put 方法是用于向队列中插入元素的核心方法之一。当队列满时,put 方法会阻塞当前线程,直到队列有空闲空间

1、put 方法的功能

  • 作用:将元素插入到队列的尾部

  • 阻塞行为:如果队列已满,当前线程会被阻塞,直到队列有空闲空间

  • 线程安全:put 方法是线程安全的,内部通过锁机制实现同步

2、put 方法的源码分析

以下是 ArrayBlockingQueue 中 put 方法的源码(基于 JDK 17):

关键点解析

  • 1、获取锁:

    • 使用 lock.lockInterruptibly() 获取锁,支持线程中断

    • 如果当前线程被中断,会抛出 InterruptedException

  • 2、检查队列是否满:

    • 如果队列满(count == items.length),调用 notFull.await() 使当前线程等待

    • notFull 是一个 Condition 对象,用于表示队列未满的条件

  • 3、插入元素:

    • 如果队列未满,调用 enqueue(e) 方法将元素插入队列

    • enqueue 方法会更新队列的 putIndex 和 count,并唤醒等待 notEmpty 条件的消费者线程

  • 4、释放锁:

    • 在 finally 块中释放锁,确保锁一定会被释放,避免死锁

3、enqueue 方法的源码分析

enqueue 是 put 方法中用于实际插入元素的私有方法。以下是其源码:

关键点解析

  • 1、插入元素:

    • 将元素 x 放入数组的 putIndex 位置

    • putIndex 是下一个插入元素的位置

  • 2、更新 putIndex:

    • 如果 putIndex 达到数组长度,将其重置为 0,实现循环数组的效果
  • 3、更新元素数量:

    • count 表示队列中的元素数量,插入成功后递增
  • 4、唤醒消费者线程:

    • 调用 notEmpty.signal() 唤醒等待 notEmpty 条件的消费者线程

4、put 方法的阻塞机制

put 方法的阻塞行为是通过 Condition 的 await() 方法实现的。以下是其工作原理:

1、队列满时的阻塞:

  • 如果队列满,当前线程会调用 notFull.await(),释放锁并进入等待状态

  • 线程会被加入到 notFull 条件的等待队列中

2、被唤醒的条件:

  • 当消费者线程从队列中移除一个元素时,会调用 notFull.signal() 或 notFull.signalAll(),唤醒等待 notFull 条件的生产者线程

  • 被唤醒的线程会重新尝试获取锁,并检查队列是否仍然满

3、中断处理::

  • 如果线程在等待期间被中断,await() 方法会抛出 InterruptedException,并清除中断状态

5、put 方法的性能优化

1、循环数组:

  • ArrayBlockingQueue 使用循环数组存储元素,避免了数组的频繁扩容和数据拷贝

  • 通过 putIndex 和 takeIndex 实现队列的循环利用

2、锁分离:

  • 使用单独的 Condition 对象(notFull 和 notEmpty)分别管理生产者和消费者的等待队列,减少锁竞争

3、公平性:

  • 可以通过构造函数指定是否使用公平锁。公平锁会按照线程等待的顺序分配锁,避免线程饥饿。

二、总结

ArrayBlockingQueue 的 put 方法通过以下机制实现了线程安全的阻塞插入:

1、锁机制:使用 ReentrantLock 保证线程安全。

2、条件变量:使用 notFull 和 notEmpty 管理线程的等待和唤醒。

3、循环数组:通过循环数组高效管理队列元素。

ArrayBlockingQueue的put方法底层原理的更多相关文章

  1. KVO-基本使用方法-底层原理探究-自定义KVO-对容器类的监听

    书读百变,其义自见! 将KVO形式以代码实现呈现,通俗易懂,更容易掌握 :GitHub   -链接如果失效请自动搜索:https://github.com/henusjj/KVO_base 代码中有详 ...

  2. synchronized底层原理

    synchronized底层语义原理 Java 虚拟机中的同步(Synchronization)基于进入和退出管程(Monitor)对象实现. 在 Java 语言中,同步用的最多的地方可能是被 syn ...

  3. HashMap底层原理分析(put、get方法)

    1.HashMap底层原理分析(put.get方法) HashMap底层是通过数组加链表的结构来实现的.HashMap通过计算key的hashCode来计算hash值,只要hashCode一样,那ha ...

  4. 红黑树规则,TreeSet原理,HashSet特点,什么是哈希值,HashSet底层原理,Map集合特点,Map集合遍历方法

    ==学习目标== 1.能够了解红黑树 2.能够掌握HashSet集合的特点以及使用(特点以及使用,哈希表数据结构) 3.能够掌握Map集合的特点以及使用(特点,常见方法,Map集合的遍历) 4.能够掌 ...

  5. Java面试底层原理

    面试发现经常有些重复的面试问题,自己也应该学会记录下来,最好自己能做成笔记,在下一次面的时候说得有条不紊,深入具体,面试官想必也很开心.以下是我个人总结,请参考: HashSet底层原理:(问了大几率 ...

  6. 【T-SQL进阶】02.理解SQL查询的底层原理

    本系列[T-SQL]主要是针对T-SQL的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础]02.联接查询 [T-SQL基础]03.子查询 [T-SQL基础]04.表表达式 ...

  7. HashMap的底层原理

    简单说: 底层原理就是采用数组加链表: 两张图片很清晰地表明存储结构: 既然是线性数组,为什么能随机存取?这里HashMap用了一个小算法,大致是这样实现: // 存储时: int hash = ke ...

  8. 操作系统底层原理与Python中socket解读

    目录 操作系统底层原理 网络通信原理 网络基础架构 局域网与交换机/网络常见术语 OSI七层协议 TCP/IP五层模型讲解 Python中Socket模块解读 TCP协议和UDP协议 操作系统底层原理 ...

  9. Servlet底层原理、Servlet实现方式、Servlet生命周期

    Servlet简介 Servlet定义 Servlet是一个Java应用程序,运行在服务器端,用来处理客户端请求并作出响应的程序. Servlet的特点 (1)Servlet对像,由Servlet容器 ...

  10. JavaScript是如何工作的: CSS 和 JS 动画底层原理及如何优化它们的性能

    摘要: 理解浏览器渲染. 原文:JavaScript是如何工作的: CSS 和 JS 动画底层原理及如何优化它们的性能 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 这是专门探索 J ...

随机推荐

  1. 深入解析 Spring AI 系列:解析函数调用

    我们之前讨论并实践过通过常规的函数调用来实现 AI Agent 的设计和实现.但是,有一个关键点我之前并没有详细讲解.今天我们就来讨论一下,如何让大模型只决定是否调用某个函数,但是Spring AI ...

  2. 深入了解SSH

    学习:深入了解SSH ssh 有商业和开源版本,其中openssh是开源中最流行的. ssh历史 1995 年 7 月, 芬兰学者Tatu Ylonen 以免费软件的形式将一套保护信息传输的程序(也就 ...

  3. Kotlin:【异常处理】自定义异常、先决条件函数

  4. linux下自建NAS教程

    NAS,英文全名Network Attached Storage,翻译过来是:网络附接存储. 引用维基百科定义 网络附接存储(英语:Network Attached Storage,缩写:NAS)[1 ...

  5. 理解ABP的领域驱动设计

    大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进. 关于玩转ABP框架相关的文章,之前在博客园陆续写了<ABP vNext系列文 ...

  6. JAVA运算符及实例

    JAVA语言支持以下运算符 优先级() 算数运算符:+,-,*,/,%,++,-- 实例1:  package operator; ​ public class Demo01 {     public ...

  7. CentOS7安装RabbitMQ (安装包安装)

    环境: CentOS7 需要安装:erlang 22.2  rabbitmq 3.8.3 参考: rabbit官网地址:http://www.rabbitmq.com/which-erlang.htm ...

  8. Drasi Sources SDK

    什么是Drasi数据源(Source)? Source提供了与系统的连接,Drasi 可以将这些系统视为变化源.source 在 Drasi 中执行三个重要功能: 处理源系统生成的更改日志/源,并将这 ...

  9. 自适应 Simpson 积分法学习笔记

    自适应 Simpson 积分法,是一种计算一段区间内,形态奇怪的函数和的算法,例如面积并和难以直接用通项公式计算的函数. Simpson 积分 我们都知道,求解微积分需要求解一个导数的原函数,但这显然 ...

  10. 软件工程: SDLC V模型

    V型 V-model 代表一个开发过程,可以被认为是瀑布模型的扩展,是更通用的 V-model 的一个例子.不是以线性方式向下移动,而是在编码阶段之后向上弯曲工艺步骤,以形成典型的 V 形.V 模型展 ...