ArrayBlockingQueue的poll方法底层原理
一、ArrayBlockingQueue的poll方法底层原理
ArrayBlockingQueue 是 Java 并发包 (java.util.concurrent) 中的一个基于数组实现的有界阻塞队列。它的 poll() 方法是用于从队列中移除并返回队首元素的核心方法之一。与 take() 方法不同,poll() 方法在队列为空时不会阻塞,而是立即返回 null。
1、poll() 方法的功能
作用:移除并返回队列的队首元素。
非阻塞行为:如果队列为空,立即返回 null,不会阻塞当前线程。
线程安全:poll() 方法是线程安全的,内部通过锁机制实现同步。
2、poll() 方法的源码分析
以下是 ArrayBlockingQueue 中 poll() 方法的源码(基于 JDK 17):

关键点解析
1、获取锁:
使用 lock.lock() 获取锁,确保线程安全。
如果锁被其他线程持有,当前线程会阻塞,直到获取锁。
2、检查队列是否空:
如果队列空(count == 0),直接返回 null。
如果队列非空,调用 dequeue() 方法移除并返回队首元素。
3、释放锁:
- 在 finally 块中释放锁,确保锁一定会被释放,避免死锁。
3、dequeue() 方法的源码分析
dequeue 是 poll() 方法中用于实际移除元素的私有方法。以下是其源码:

关键点解析
1、获取队首元素:
从数组的 takeIndex 位置获取队首元素。
takeIndex 是下一个移除元素的位置。
2、清除队首元素:
- 将 takeIndex 位置的元素设置为 null,帮助垃圾回收。
3、更新 takeIndex:
- 如果 takeIndex 达到数组长度,将其重置为 0,实现循环数组的效果。
4、更新元素数量:
- count 表示队列中的元素数量,移除成功后递减。
5、唤醒生产者线程:
- 调用 notFull.signal() 唤醒等待 notFull 条件的生产者线程。
4、poll() 方法的非阻塞机制
poll() 方法的非阻塞行为是通过直接检查队列是否空来实现的。如果队列空,立即返回 null,不会调用 await() 方法阻塞当前线程。
5、poll() 方法的性能优化
循环数组:
ArrayBlockingQueue 使用循环数组存储元素,避免了数组的频繁扩容和数据拷贝。
通过 putIndex 和 takeIndex 实现队列的循环利用。
锁分离:
- 使用单独的 Condition 对象(notFull 和 notEmpty)分别管理生产者和消费者的等待队列,减少锁竞争。
公平性:
- 可以通过构造函数指定是否使用公平锁。公平锁会按照线程等待的顺序分配锁,避免线程饥饿。
二、总结
ArrayBlockingQueue 的 poll() 方法通过以下机制实现了线程安全的非阻塞移除:
1、锁机制:使用 ReentrantLock 保证线程安全。
2、非阻塞行为:如果队列空,立即返回 null,不会阻塞当前线程。
3、循环数组:通过循环数组高效管理队列元素。
ArrayBlockingQueue的poll方法底层原理的更多相关文章
- KVO-基本使用方法-底层原理探究-自定义KVO-对容器类的监听
书读百变,其义自见! 将KVO形式以代码实现呈现,通俗易懂,更容易掌握 :GitHub -链接如果失效请自动搜索:https://github.com/henusjj/KVO_base 代码中有详 ...
- synchronized底层原理
synchronized底层语义原理 Java 虚拟机中的同步(Synchronization)基于进入和退出管程(Monitor)对象实现. 在 Java 语言中,同步用的最多的地方可能是被 syn ...
- HashMap底层原理分析(put、get方法)
1.HashMap底层原理分析(put.get方法) HashMap底层是通过数组加链表的结构来实现的.HashMap通过计算key的hashCode来计算hash值,只要hashCode一样,那ha ...
- Linux高级字符设备驱动 poll方法(select多路监控原理与实现)
1.什么是Poll方法,功能是什么? 2.Select系统调用(功能) Select系统调用用于多路监控,当没有一个文件满足要求时,select将阻塞调用进程. int selec ...
- 红黑树规则,TreeSet原理,HashSet特点,什么是哈希值,HashSet底层原理,Map集合特点,Map集合遍历方法
==学习目标== 1.能够了解红黑树 2.能够掌握HashSet集合的特点以及使用(特点以及使用,哈希表数据结构) 3.能够掌握Map集合的特点以及使用(特点,常见方法,Map集合的遍历) 4.能够掌 ...
- Java面试底层原理
面试发现经常有些重复的面试问题,自己也应该学会记录下来,最好自己能做成笔记,在下一次面的时候说得有条不紊,深入具体,面试官想必也很开心.以下是我个人总结,请参考: HashSet底层原理:(问了大几率 ...
- 并发队列:ArrayBlockingQueue实际运用场景和原理
ArrayBlockingQueue实际应用场景 之前在某公司做过一款情绪识别的系统,这套系统通过调用摄像头接口采集人脸信息,将采集的人脸信息做人脸识别和情绪分析,最终经过一定的算法将个人情绪数据转化 ...
- Java8线程池ThreadPoolExecutor底层原理及其源码解析
小侃一下 日常开发中, 或许不会直接new线程或线程池, 但这些线程相关的基础或思想是非常重要的, 参考林迪效应; 就算没有直接用到, 可能间接也用到了类似的思想或原理, 例如tomcat, jett ...
- 【T-SQL进阶】02.理解SQL查询的底层原理
本系列[T-SQL]主要是针对T-SQL的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础]02.联接查询 [T-SQL基础]03.子查询 [T-SQL基础]04.表表达式 ...
- HashMap的底层原理
简单说: 底层原理就是采用数组加链表: 两张图片很清晰地表明存储结构: 既然是线性数组,为什么能随机存取?这里HashMap用了一个小算法,大致是这样实现: // 存储时: int hash = ke ...
随机推荐
- 深入理解第一范式(1NF):数据库设计中的基础与实践
title: 深入理解第一范式(1NF):数据库设计中的基础与实践 date: 2025/1/15 updated: 2025/1/15 author: cmdragon excerpt: 在关系型数 ...
- Codeforces Round 968 (Div. 2)
题目链接:Codeforces Round 968 (Div. 2) - Codeforces 总结:C题想到了,但是写成shi了,出得有点慢. A. Turtle and Good String t ...
- Volar Vetur 在 VSCode 里的配置
VSCode 对 vue2 vue3 项目如何配置 1. 在 vscode 安装 vetur.Vue - Official(之前叫 Volar) 两个插件 2.你若是 vue3 项目,直接在你项目工作 ...
- Vmware共享文件夹安装设置方法(window与Linux使用共享文件夹)
Vmware共享文件夹安装设置方法 注意:如果按照了工具,设置了共享文件夹,Linux下面还是没有的话,可以运行下面的命令,就会加载共享文件夹了 vmhgfs-fuse .host:/ /mnt/hg ...
- Hetao P1307 树的剖分 题解 [ 蓝 ] [ 树形 dp ] [ 贪心 ]
树的剖分:很厉害的性质题,代码也很好写.运用到了奇偶性拼凑答案的 trick. 观察 首先发现一个很重要的条件:一个点的点权只可能是 \(0,1,2\). 这个条件开始我们可能无法用上,于是先想最后的 ...
- Luogu P1220 关路灯 题解 [ 蓝 ][ 区间dp ]
原题 关路灯 题目描述 某一村庄在一条路线上安装了 \(n\) 盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少).老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏一盏 ...
- 还堵在高速路上吗?带你进入Scratch世界带你飞
国庆假期高速路的风景 国庆假期正式启动人从众模式,无论是高速公路还是景区,不管是去程还是回程,每一次都堪称经典. 一些网友在经历漫长的拥堵后 哭笑不得地表示 "假期都在堵车中度过了" ...
- 《Indie Tools • 半月刊》第001期
引言:独立开发者工具分享 <INDIE TOOLS>专注于分享独立开发出海精选.最新.最实用的工具. 欢迎订阅半月刊:<INDIE TOOLS • 半月刊> 如果本文能给你提供 ...
- IPMITool 工具使用详细教程
IPMITool 工具使用详细教程 一.IPMI 与 IPMITool 简介 1. IPMI 概述 智能平台管理接口(Intelligent Platform Management Interface ...
- 仓储层当前有接口 IRepository<T> 抽象类 BaseRepository<T> 业务逻辑层有抽象类 BaseBusiness<M, E> 接口 IBusiness<M, E> 请用C# 给出一个案例,支持不同表对应不同的业务逻辑层,然后不同仓储实例。
以下是一个简单的C#示例,展示了如何实现不同表对应不同的业务逻辑层和不同的仓储实例: // 仓储层 public interface IRepository<T> { void Add(T ...