目录

介绍

数据结构

方法实现

offer,poll,peek

put,take

enqueue,dequeue

注意

参考


介绍

是一个用数组实现的有界阻塞队列,此队列按照先进先出(FIFO)的原则对元素进行排序。支持公平锁和非公平锁。【注:每一个线程在获取锁的时候可能都会排队等待,如果在等待时间上,先获取锁的线程的请求一定先被满足,那么这个锁就是公平的。反之,这个锁就是不公平的。公平的获取锁,也就是当前等待时间最长的线程先获取锁】。

锁控制参考:ReentrantLock源码

数据结构

/**队列元素 */
final Object[] items;/** items index for next take, poll, peek or remove */
int takeIndex;/** items index for next put, offer, or add */
int putIndex;/** 以入队数量 */
int count;/** 锁控制 */
final ReentrantLock lock;/** Condition for waiting takes */
private final Condition notEmpty;/** Condition for waiting puts */
private final Condition notFull;/* iterator */transient Itrs itrs = null;

方法实现

offer,poll,peek

    public boolean offer(E e) {checkNotNull(e);final ReentrantLock lock = this.lock;lock.lock();try {if (count == items.length)return false;else {enqueue(e);return true;}} finally {lock.unlock();}}public boolean offer(E e, long timeout, TimeUnit unit)throws InterruptedException {checkNotNull(e);long nanos = unit.toNanos(timeout);final ReentrantLock lock = this.lock;lock.lockInterruptibly();try {while (count == items.length) {if (nanos <= 0)return false;nanos = notFull.awaitNanos(nanos);}enqueue(e);return true;} finally {lock.unlock();}}public E poll() {final ReentrantLock lock = this.lock;lock.lock();try {return (count == 0) ? null : dequeue();} finally {lock.unlock();}}public E poll(long timeout, TimeUnit unit) throws InterruptedException {long nanos = unit.toNanos(timeout);final ReentrantLock lock = this.lock;lock.lockInterruptibly();try {while (count == 0) {if (nanos <= 0)return null;nanos = notEmpty.awaitNanos(nanos);}return dequeue();} finally {lock.unlock();}}public E peek() {final ReentrantLock lock = this.lock;lock.lock();try {return itemAt(takeIndex); // null when queue is empty} finally {lock.unlock();}}

put,take

    public void put(E e) throws InterruptedException {checkNotNull(e);final ReentrantLock lock = this.lock;lock.lockInterruptibly();try {while (count == items.length)notFull.await();enqueue(e);} finally {lock.unlock();}}public E take() throws InterruptedException {final ReentrantLock lock = this.lock;lock.lockInterruptibly();try {while (count == 0)notEmpty.await();return dequeue();} finally {lock.unlock();}}

enqueue,dequeue

    private void enqueue(E x) {// assert lock.getHoldCount() == 1;// assert items[putIndex] == null;final Object[] items = this.items;//在put index 放置元素items[putIndex] = x;//如果putIndex +1 == items.length,则设置为0,循环数组。if (++putIndex == items.length)putIndex = 0;count++;notEmpty.signal();}private E dequeue() {// assert lock.getHoldCount() == 1;// assert items[takeIndex] != null;final Object[] items = this.items;@SuppressWarnings("unchecked")E x = (E) items[takeIndex];items[takeIndex] = null;if (++takeIndex == items.length)takeIndex = 0;count--;if (itrs != null)itrs.elementDequeued();notFull.signal();return x;}void removeAt(final int removeIndex) {// assert lock.getHoldCount() == 1;// assert items[removeIndex] != null;// assert removeIndex >= 0 && removeIndex < items.length;final Object[] items = this.items;//是第一个元素。if (removeIndex == takeIndex) {// removing front item; just advanceitems[takeIndex] = null;if (++takeIndex == items.length)takeIndex = 0;count--;if (itrs != null)itrs.elementDequeued();} else {// an "interior" remove// slide over all others up through putIndex.final int putIndex = this.putIndex;//i位置值设为null,后续节点全部前移,直到putIndex,并且把putIndex -1;for (int i = removeIndex;;) {int next = i + 1;if (next == items.length)next = 0;if (next != putIndex) {items[i] = items[next];i = next;} else {items[i] = null;this.putIndex = i;break;}}count--;if (itrs != null)itrs.removedAt(removeIndex);}notFull.signal();}

注意

数组是个循环数组,当下标为item.length时则为0。

参考

  • ReentrantLock源码
  • Java并发包--阻塞队列(BlockingQueue)

ArrayBlockingQueue源码相关推荐

  1. 面试官系统精讲Java源码及大厂真题 - 22 ArrayBlockingQueue 源码解析

    22 ArrayBlockingQueue 源码解析 耐心和恒心总会得到报酬的. 引导语 本小节我们来介绍本章最后一个队列:ArrayBlockingQueue.按照字面翻译,中文叫做数组阻塞队列,从 ...

  2. Android多线程之ArrayBlockingQueue源码解析

    阻塞队列系列 Android多线程之LinkedBlockingQueue源码解析 Android多线程之SynchronousQueue源码解析 Andorid多线程之DelayQueue源码分析 ...

  3. 阻塞队列和ArrayBlockingQueue源码解析

    什么是阻塞队列 当队列中为空时,从队列总获取元素的操作将被阻塞,当队列满时,向队列中添加元素的操作将被阻塞.试图从空的阻塞队列中获取元素的线程将会被阻塞,知道其它的线程往队列中插入新的元素.同样,试图 ...

  4. Java8 ArrayBlockingQueue 源码阅读

    一.什么是 ArrayBlockingQueue ArrayBlockingQueue 是 GUC(java.util.concurrent) 包下的一个线程安全的阻塞队列,底层使用数组实现. 除了线 ...

  5. java queue源码_Java高并发系列之ArrayBlockingQueue源码解析

    JUC包下定义了一个接口:BlockingQueue.其实现类有ArrayBlockingQueue等.本文先来介绍一下ArrayBlockingQueue.从字面可以看出,ArrayBlocking ...

  6. ArrayBlockingQueue源码解析(JDK1.8)

    ArrayBlockingQueue是基于数组的先进先出的有界循环队列 同样我们还是先上类的关系图 从类的关系图中可以看出ArrayBlockingQueue继承一个抽象类和实现了两个接口,然后分别简 ...

  7. Java8 ArrayBlockingQueue 源码解析

    目录 1.定义 2.构造方法 3.add / offer / put 4.poll / take / peek 5.remove / clear /drainTo 6.iterator / Itr / ...

  8. 【JUC】JDK1.8源码分析之ArrayBlockingQueue(三)

    一.前言 在完成Map下的并发集合后,现在来分析ArrayBlockingQueue,ArrayBlockingQueue可以用作一个阻塞型队列,支持多任务并发操作,有了之前看源码的积累,再看Arra ...

  9. 阻塞队列(ArrayBlockingQueue) 迭代器源码分析

    文章目录 为什么 ArrayBlockingQueue 迭代器复杂呢? 提出几个 ArrayBlockingQueue 迭代器的问题用于下面代码分析时进行思考 Itrs Itr 1.重要变量 2. 构 ...

最新文章

  1. 职场中一路走来却拂不去一丝失落——一个女IT的告白
  2. tcp连接的三次握手
  3. U-Mail邮件服务器树状通讯录实现智能化应用
  4. C++ STL string的属性
  5. 农行软开是总行编制吗_2021农行总行校招笔试来啦,你知道农行笔试都考些什么吗?...
  6. Springboot 整合jsp案例
  7. 图像处理基本概念——卷积,滤波,平滑
  8. 电大计算机网络技术基础,电大--2016年电大 计算机与网络技术基础小抄已排版.doc...
  9. Java-Collection、List
  10. 解决用户意外退出在线列表无法及时更新问题2(转载)
  11. SQL Server 2008 R2的完全卸载
  12. 使用JS 实现 分享到 新浪微博 QQ 空间
  13. 第四周问题:Tu Hao's Problem
  14. linux下配置Tilera MDE4.1.8方法
  15. iOS上线APP在App Store地址
  16. 网络世界强权崛起,全球竞相取经
  17. IEC 61000系列标准及其对应国标
  18. linux 安装cvs,在Linux中安装CVS
  19. PMP认证对IT企业有多大用处?
  20. css设置div上下左右均居中 、底部居中

热门文章

  1. xajax中的中文乱码问题
  2. 【struts2】struts2配置文件—struts.xml
  3. 【Java线程】互斥 同步 异步 并发 多线程的区别与联系
  4. Sharepoint 2010配置form认证方式(SQL账号)
  5. ANSI,ASCII,Unicode的区别与联系
  6. java视频教程不同阶段看哪些
  7. 专家系列教程:遭受***后的证据有哪些?
  8. JDK5--Annotation学习:基础(一)
  9. DHTML之-----document.selection 的 createRange
  10. c语言程序参数mook,C语言程序设计-中国大学mooc-题库零氪