ArrayBlockingQueue是一个先进先出线程安全的队列,队列头部是进入队列时间最长的元素,队尾是进入队列时间最短的元素,同时队列的最大容量是固定的。

先看类定义:

 public class ArrayBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable {
      ......
}
ArrayBlockingQueue实现了BlockingQueue接口,是一个阻塞队列实现,内部通过数组进行数据存储:
  /** The queued items */
final Object[] items; /** items index for next take, poll, peek or remove */
int takeIndex; /** items index for next put, offer, or add */
int putIndex;

对元素的增加操作,主要提供了三种使用场景:添加(队列已满则返回false)、限时等待添加,无限等待添加;

   /**
* Inserts the specified element at the tail of this queue if it is
* possible to do so immediately without exceeding the queue's capacity,
* returning {@code true} upon success and throwing an
* {@code IllegalStateException} if this queue is full.
*
* @param e the element to add
* @return {@code true} (as specified by {@link Collection#add})
* @throws IllegalStateException if this queue is full
* @throws NullPointerException if the specified element is null
*/
public boolean add(E e) { //add 和offer(e) 是一样的
return super.add(e);
} /**
* Inserts the specified element at the tail of this queue if it is
* possible to do so immediately without exceeding the queue's capacity,
* returning {@code true} upon success and {@code false} if this queue
* is full. This method is generally preferable to method {@link #add},
* which can fail to insert an element only by throwing an exception.
*
* @throws NullPointerException if the specified element is null
*/
public boolean offer(E e) {
checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (count == items.length)
return false;
else {
insert(e);
return true;
}
} finally {
lock.unlock();
}
} /**
* Inserts the specified element at the tail of this queue, waiting
* for space to become available if the queue is full.
*
* @throws InterruptedException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
public void put(E e) throws InterruptedException {
checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == items.length)
notFull.await();
insert(e);
} finally {
lock.unlock();
}
} /**
* Inserts the specified element at the tail of this queue, waiting
* up to the specified wait time for space to become available if
* the queue is full.
*
* @throws InterruptedException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
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);
}
insert(e);
return true;
} finally {
lock.unlock();
}
}

对元素的获取同样提供了三种使用场景:添加(队列空则返回null)、限时等待获取,无限等待获取;

  public E poll() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return (count == 0) ? null : extract();
} finally {
lock.unlock();
}
} public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == 0)
notEmpty.await();
return extract();
} 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 extract();
} finally {
lock.unlock();
}
}

获取队列元素大小也是强一致性的:

   /**
* Returns the number of elements in this queue.
*
* @return the number of elements in this queue
*/
public int size() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return count;
} finally {
lock.unlock();
}
}

元素的删除也是同步的,元素存在则删除返回true,如果元素不存在则返回false:

   /**
* Removes a single instance of the specified element from this queue,
* if it is present. More formally, removes an element {@code e} such
* that {@code o.equals(e)}, if this queue contains one or more such
* elements.
* Returns {@code true} if this queue contained the specified element
* (or equivalently, if this queue changed as a result of the call).
*
* <p>Removal of interior elements in circular array based queues
* is an intrinsically slow and disruptive operation, so should
* be undertaken only in exceptional circumstances, ideally
* only when the queue is known not to be accessible by other
* threads.
*
* @param o element to be removed from this queue, if present
* @return {@code true} if this queue changed as a result of the call
*/
public boolean remove(Object o) {
if (o == null) return false;
final Object[] items = this.items;
final ReentrantLock lock = this.lock;
lock.lock();
try {
for (int i = takeIndex, k = count; k > 0; i = inc(i), k--) {
if (o.equals(items[i])) {
removeAt(i);
return true;
}
}
return false;
} finally {
lock.unlock();
}
}

ArrayBlockingQueue的所有操作都是通过加锁进行同步的,代码也比较简单。

												

java1.7集合源码阅读:ArrayBlockingQueue的更多相关文章

  1. java1.7集合源码阅读: Stack

    Stack类也是List接口的一种实现,也是一个有着非常长历史的实现,从jdk1.0开始就有了这个实现. Stack是一种基于后进先出队列的实现(last-in-first-out (LIFO)),实 ...

  2. java1.7集合源码阅读: Vector

    Vector是List接口的另一实现,有非常长的历史了,从jdk1.0开始就有Vector了,先于ArrayList出现,与ArrayList的最大区别是:Vector 是线程安全的,简单浏览一下Ve ...

  3. 关于java1.7集合源码阅读

    工作中每天都会和java集合打交道,虽然以前也看过jdk源码的实现,但有些东西时间长了还是会遗忘,或者有些实现在新版本中有了新的变化,俗话说"温故而知新",所以打算再阅读一下相关源 ...

  4. java1.7集合源码阅读:LinkedList

    先看看类定义: public class LinkedList<E> extends AbstractSequentialList<E> implements List< ...

  5. java1.7集合源码阅读:ArrayList

    ArrayList是jdk1.2开始新增的List实现,首先看看类定义: public class ArrayList<E> extends AbstractList<E> i ...

  6. 【JDK1.8】JDK1.8集合源码阅读——IdentityHashMap

    一.前言 今天我们来看一下本次集合源码阅读里的最后一个Map--IdentityHashMap.这个Map之所以放在最后是因为它用到的情况最少,也相较于其他的map来说比较特殊.就笔者来说,到目前为止 ...

  7. 【JDK1.8】JDK1.8集合源码阅读——总章

    一.前言 今天开始阅读jdk1.8的集合部分,平时在写项目的时候,用到的最多的部分可能就是Java的集合框架,通过阅读集合框架源码,了解其内部的数据结构实现,能够深入理解各个集合的性能特性,并且能够帮 ...

  8. 【JDK1.8】JDK1.8集合源码阅读——HashMap

    一.前言 笔者之前看过一篇关于jdk1.8的HashMap源码分析,作者对里面的解读很到位,将代码里关键的地方都说了一遍,值得推荐.笔者也会顺着他的顺序来阅读一遍,除了基础的方法外,添加了其他补充内容 ...

  9. 【JDK1.8】JDK1.8集合源码阅读——ArrayList

    一.前言 在前面几篇,我们已经学习了常见了Map,下面开始阅读实现Collection接口的常见的实现类.在有了之前源码的铺垫之后,我们后面的阅读之路将会变得简单很多,因为很多Collection的结 ...

随机推荐

  1. javaScript编辑器sublime的安装

    最近在学习js,学习任何一门语言之前,当然免不了最初的环境安装: 见:http://www.cnblogs.com/zhcncn/p/4113589.html

  2. TouTiao开源项目 分析笔记13 最后一个订阅号的实现主页面

    1.实现订阅号的基础类 1.1.本地订阅号的Bean类==>MediaChannelBean public class MediaChannelBean implements Parcelabl ...

  3. python 按位置关系输出矩阵元素

    描述:依次输出矩阵中最近邻的元素 例如:输入: [[1, 2, 3] [4, 5, 6] [7, 8, 9]] 输出: [[ 1.  2.  4.  5.  3.  6.  7.  8.  9.] [ ...

  4. 顺序查找&二分查找&索引查找

    1.查找技术的分类.如下图: 2.什么是顺序查找呢?(无序表) 顺序查找的原理很简单,就是遍历整个列表,逐个进行记录的关键字与给定值比较,若某个记录的关键字和给定值相等,则查找成功,找到所查的记录.如 ...

  5. java前台传参json,后台用map或者实体对象接收

    (一)前台传js对象,里面包含数组,后台用map接收 (1)第一种情况:数组里不包含js对象 var param ={}: param.id=id; param.name=name; var scor ...

  6. laravel5.5表单验证

    1. 在第一次验证失败后停止 有时,你希望在某个属性第一次验证失败后停止运行验证规则.为了达到这个目的,附加 bail 规则到该属性: $this->validate($request, [ ' ...

  7. 《Cracking the Coding Interview》——第17章:普通题——题目10

    2014-04-28 23:54 题目:XML文件的冗余度很大,主要在于尖括号里的字段名.按照书上给定的方式进行压缩. 解法:这题我居然忘做了,只写了一句话的注解.用python能够相对方便地实现,因 ...

  8. python学习总结---文件操作

    # 文件操作 ### 目录管理(os) - 示例 ```python # 执行系统命令 # 清屏 # os.system('cls') # 调出计算器 # os.system('calc') # 查看 ...

  9. iPhone:iOS界面,本地生成随机验证码

    本文博客,模仿杰瑞教育的一篇博文,并在它的基础上,进行了些许更改.同时在重写的过程中,对自己忽略的地方,进行了重新认识,受益匪浅.文章来源:http://www.cnblogs.com/jerehed ...

  10. Android事件分发机制详解(2)----分析ViewGruop的事件分发

    首先,我们需要 知道什么是ViewGroup,它和普通的View有什么区别? ViewGroup就是一组View的集合,它包含很多子View和ViewGroup,是Android 所有布局的父类或间接 ...