ArrayBlockingQueue是JDK1.5开始concurrent包中提供的并发工具类,是一个基于数组的有界的先进先出队列,如果加入元素时,数组已满,或数组为空时,取元素都会阻塞当前线程,是一个典型的生产者消费者模式。类似的类还有LinkedBlockingQueue,PriorityBlockingQueue。

继承关系

public class ArrayBlockingQueue extends AbstractQueue

implements BlockingQueue, java.io.Serializable

public interface BlockingQueue extends Queue

核心成员变量

final Object[] items; //保存元素

/** items index for next take, poll, peek or remove */

int takeIndex; //指向队头

/** items index for next put, offer, or add */

int putIndex; //指向队尾

/** Number of elements in the queue */

int count; //队中元素计数

/*

* Concurrency control uses the classic two-condition algorithm

* found in any textbook.

*/

/** Main lock guarding all access */

final ReentrantLock lock; //可重入锁

/** Condition for waiting takes */

private final Condition notEmpty; //条件变量

/** Condition for waiting puts */

private final Condition notFull; //条件变量

构造方法

public ArrayBlockingQueue(int capacity, boolean fair) {

if (capacity <= 0)

throw new IllegalArgumentException();

this.items = new Object[capacity]; //初始化指定大小的有界队列

lock = new ReentrantLock(fair); //fair指示该锁是否是公平的

notEmpty = lock.newCondition();

notFull = lock.newCondition();

}

添加元素:put方法

public void put(E e) throws InterruptedException {

checkNotNull(e);

final ReentrantLock lock = this.lock;

lock.lockInterruptibly();

try {

while (count == items.length)

notFull.await(); //添加元素时,如果已满,则阻塞当前线程,等待在notFull这个条件变量上,等待notFull调用signal唤醒

enqueue(e); //此时队列肯定未满

} finally {

lock.unlock();

}

}

private void enqueue(E x) {

// assert lock.getHoldCount() == 1;

// assert items[putIndex] == null;

final Object[] items = this.items;

items[putIndex] = x; //将元素加入队尾

if (++putIndex == items.length) //将putIndex加1,如果到达数组尾部,则从0开始

putIndex = 0;

count++; //增加计数

notEmpty.signal(); //增加一个元素后,如果有线程等待在noEmpty条件变量上,通知并唤醒一种一个线程。

}

put方法首先判断队列是否已满,如果已满,则阻塞当前线程,等待在notFull这个条件变量上,等待notFull调用signal唤醒。当队列非空时,将该元素加入队尾,增加元素计数,唤醒因为进行去操作时数组为空而等待在notEmpty上的线程,通知它此时队列已经有元素了,你可以进行取操作了。

取元素:take方法

public E take() throws InterruptedException {

final ReentrantLock lock = this.lock;

lock.lockInterruptibly();

try {

while (count == 0)

notEmpty.await(); //取元素但是队列为空时,阻塞线程,等待在notEmpty上

return dequeue(); //此时,队列肯定非空,进行出队操作

} finally {

lock.unlock();

}

}

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--; //计数减1

if (itrs != null)

itrs.elementDequeued();

notFull.signal(); //通知因为添加元素但是队列已满时而阻塞的线程,队列此时可插入了

return x; //返回队头元素

}

take方法和put方法类似,先检查队列是否为空,队列为空时,阻塞线程,等待在notEmpty上。当队列非空时,进行出队操作。同时还要通知因为添加元素但是队列已满时而阻塞的线程,队列此时可插入了。

java+arrayblockquene_Java源码分析-ArrayBlockingQueue相关推荐

  1. java web开源项目源码_超赞!推荐一个专注于Java后端源码分析的Github项目!

    大家好,最近有小伙伴们建议我把源码分析文章及源码分析项目(带注释版)放到github上,这样小伙伴们就可以把带中文注释的源码项目下载到自己本地电脑,结合源码分析文章自己本地调试,总之对于学习开源项目源 ...

  2. Java集合源码分析(二)ArrayList

    ArrayList简介 ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单线程环境下,多线 ...

  3. Java IO源码分析(四)——PrintStream

    简介 PrintStream继承于FilterOutputStream,而FilterOutputStream用于封装其他的输出流. PrintStream用于给其他的输出流封装了一层打印的功能,它内 ...

  4. java abstractlist_源码分析-java-AbstractList-Itr和ListItr的实现

    AbstractList API文档 AbstractList实现了List接口,又因为List继承自Collection,Collection继承自Iterable.因此List接口包含很多的方法. ...

  5. Java Stream源码分析及知识点总结

    概述 什么是Stream Stream就是一种流式的处理数据风格,这一种风格将要处理的元素集合看作一种流,流在管道中传输,并且可以在管道的节点上进行处理,比如进行筛选.排序和聚合.通俗地说,就是将St ...

  6. 【java】java boolean 源码分析

    1.概述 转载:jdk源码分析-------------boolean 这篇文章小编只是对boolean类型的几个方法进行一次知识梳理,大家有好的意见可以在留言区留下宝贵的意见,小编会做出相应的调整. ...

  7. Java 容器源码分析之 TreeMap

    TreeMap 是一种基于红黑树实现的 Key-Value 结构.在使用集合视图在 HashMap 中迭代时,是不能保证迭代顺序的: LinkedHashMap 使用了双向链表,保证按照插入顺序或者访 ...

  8. java编译器源码分析之语法分析器

    token流到抽象语法树的过程是语法分析. 前面认识到token流,这部分将介绍抽象语法树(AST). 那么什么是抽象语法树(AST)?AST长啥样?我们的token流是如何转变成AST的?下面围绕这 ...

  9. java 反编译器源码分析

    简介 由于工作需要反编译分析 java 源码,于是需要反编译器做些改动,所以就有了这篇文章. 这次要分析的反编译器是 Femflower,是著名 IDE Idea 的反编译器.源码也是从 Idea 开 ...

最新文章

  1. 导入语句 python_Python导入语句说明
  2. 全栈必备Linux 基础
  3. POJ1178枚举三个地方(所有点都去同一个点)
  4. MyBatis——@Result注解column参数传递——父查询函数的参数传递到子查询
  5. C语言不用循环不用递归打印0-999的小程序,你看懂了吗?
  6. 如何实现手游app瘦身?
  7. mysql bin.000047_mysql-bin.0000X 日志文件处理
  8. 改善 Python 程序的 91 个建议
  9. 一个年轻的码农的一个C#项目
  10. 浏览器兼容性问题——IE不支持却很实用的CSS属性Outline和Child
  11. 简单使用mybatis(idea中使用)
  12. 超级简单Python学生信息管理系统设计与实现.zip(论文+项目源码+使用说明书)
  13. mo汇编指令_汇编指令(汇编指令详解)
  14. 图解机器学习算法(8) | 回归树模型详解(机器学习通关指南·完结)
  15. LeetCode-Python-1386. 安排电影院座位(数组)
  16. Unity Editor 判断在哪个视图选中对象(Hierachy, Porject)
  17. android 菜鸟面单打印_android菜鸟 实战项目之简单界面实现
  18. iOS审核被拒含义及应对措施-长文
  19. python if简洁写法_Python - if-else 的多种简洁写法
  20. SQLserver获取汉字的拼音码和五笔码

热门文章

  1. docker 学习手冊-中文版下载
  2. 题解---2015年浙江理工12月校赛
  3. POJ3630——简单Trie树
  4. [注]什么是用户?估计90%人不知道
  5. 史上最全jdk版本新特性大全
  6. Java 14 发布了,不使用class也能定义类了?还顺手要干掉Lombok!
  7. 漫话:什么是云计算?
  8. 美团陶云霜:CRM平台建设实践(胶片)
  9. 李伟山:金融撮合架构
  10. 大数据之Azkaban部署