一、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. Peewee:Python 简洁强大的 ORM 框架

    在 Python 的开发世界中,数据库操作是至关重要的一环. 今天介绍的 Peewee 作为一款简洁且功能强大的 ORM(对象关系映射)框架,为开发者提供了高效便捷的数据库交互方式. 1. Peewe ...

  2. Linux基础:从命令行管理文件系统权限

  3. 第2章 C# 语言基础

    第2章 C# 语言基础 难点提纲 mindmap 第2章 C#语言基础 数值类型 数值字面量 溢出检查 特殊的浮点值 decimal 舍入误差 数组 简化初始化的<br/>两种方式 变量和 ...

  4. Django Rest Framework的使用

    Django Rest Framework 一.Rest Framework的基本介绍 程序的客户端有很多:硬件设备,游戏,APP,软件,其他的外部服务端. 1. Web应用模式 在开发Web应用中, ...

  5. redis安装、多实例和配置、及服务器性能优化

    同一台服务器部署不同应用或者同一应用部署不同环境,需要redis服务多开防止数据冲突问题. 一.安装redis 需要安装gcc编译工具 yum install gcc -y 源码安装默认Redis程序 ...

  6. DP(优化)

    史不分好坏.是史就应该冲进. 细节见其他题解. P10538 首先建出部分分 sub1 的图,发现是 DAG,于是设点为状态,即即将乘坐 \(j\) 车的最小代价 \(f_j\).这样的转移就是枚举上 ...

  7. Linux重要的日志文件

    1./var/log/boot.log 该文件记录了系统在引导过程中发生的事件,就是Linux系统开机自检过程显示的信息 2./var/log/syslog 只记录警告信息,常常是系统出问题的信息,所 ...

  8. FLink自定义Sink,生产的数据导出到Redis

    一.pom文件 https://www.cnblogs.com/robots2/p/16048648.html 二.自定义sink 2.1 自定义sink package net.xdclass.cl ...

  9. RMAN备份时遇到ORA-48132 &ORA-48170且备份变慢案例

    现象描述: 环境: 操作系统:Red Hat Enterprise Linux release 8.10 数据库版本: Oracle 19.24.0.0.0 企业版 备份作业在执行RMAN备份时,告警 ...

  10. 如何在Spring Boot项目中添加国密SM4加密支持?——基于过滤器的实现

    如何在Spring Boot项目中添加国密SM4加密支持呢?--基于过滤器的实现 引言 ​ 在数字化时代,数据安全至关重要,尤其是在API交互过程中,确保传输数据的安全性是保护隐私和机密信息的关键.中 ...