功能简介:
  • ArrayBlockingQueue是一种基于数组实现的有界的阻塞队列。队列中的元素遵循先入先出(FIFO)的规则。新元素插入到队列的尾部,从队列头部取出元素。
  • 和普通队列有所不同,该队列支持阻塞操作。比如从空队列中取元素,会导致当前线程阻塞,直到其他线程将元素放入队列;将元素插入已经满的队列,同样会导致当前线程阻塞,直到其他线程从队列中取出元素。
  • ArrayBlockingQueue也支持公平和非公平策略(针对队列中元素的存取线程,也可认为是元素的生产者和消费者)。
源码分析:
  • ArrayBlockingQueue继承了AbstractQueue并实现了BlockingQueue,AbstractQueue是Queue的公共骨架实现,这个不看了,简单看下BlockingQueue接口:
public interface BlockingQueue<E> extends Queue<E> {
/**
* 将一个元素放入队列。
* 成功返回true;失败抛IllegalStateException异常。
*/
boolean add(E e);
/**
* 将一个元素放入队列。
* 成功返回true;失败返回false。
*/
boolean offer(E e);
/**
* 将一个元素放入队列。
* 如果元素无法放入队列,当前操作线程会等待,直到元素可以放入队列。
*/
void put(E e) throws InterruptedException;
/**
* 将一个元素放入队列。
* 如果元素无法放入队列,当前操作线程会等待,直到元素可以放入队列或者
* 给定的时间超时。
* 成功返回true;超时返回false;
*/
boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException;
/**
* 从队列头部获取并删除一个元素。
* 如果无法获取元素,当前操作线程等待,直到有元素可以被获取。
*/
E take() throws InterruptedException;
/**
* 从队列头部获取并删除一个元素。
* 如果无法获取元素,当前操作线程等待,直到有元素可以被获取或者给定时间超时。
* 如果超时,返回null。
*/
E poll(long timeout, TimeUnit unit)
throws InterruptedException;
/**
* 获取队列剩余容量。
*/
int remainingCapacity();
/**
* 移除队列中和给定元素相同的元素。
*/
boolean remove(Object o);
/**
* 判断队列中是否包含给定元素。
*/
public boolean contains(Object o);
/**
* 移除队列中所有的可用元素,并把它们添加到给定集合。
*/
int drainTo(Collection<? super E> c);
/**
* 移除队列中不超过给定数量的可用元素,并把它们添加到给定集合。
*/
int drainTo(Collection<? super E> c, int maxElements);
}
       可以重点关注下put和take方法的行为。
  • 接下来看下ArrayBlockingQueue内部的数据结构:
       ArrayBlockingQueue内部结构非常简单,就是一个数组,一把锁,两个条件;也可以看到,上面提到的公平和非公平策略是由内部的重入锁来支持的。
  • 继续看下ArrayBlockingQueue的重要方法,重点看下put和take,先看下put方法:
    public void put(E e) throws InterruptedException {
if (e == null) throw new NullPointerException();
final E[] items = this.items;
final ReentrantLock lock = this.lock;
//由于需要支持方法可中断行为,这里使用可中断的锁操作。
lock.lockInterruptibly();
try {
try {
while (count == items.length)
notFull.await();//队列满时,在notFull条件上等待。
} catch (InterruptedException ie) {
notFull.signal(); // 被中断后,唤醒其他等待notFull条件的线程。
throw ie;
}
insert(e);
} finally {
lock.unlock();
}
} /**
* Circularly increment i.
*/
final int inc(int i) {
return (++i == items.length)? 0 : i;
}
/**
* 在内部数组的putIndex位置插入元素,调整putIndex和count,然后唤醒notEmpty条件上等待的线程。
* 本方法只有在持有锁的情况下才会被调用。
*/
private void insert(E x) {
items[putIndex] = x;
putIndex = inc(putIndex);
++count;
notEmpty.signal();
}

再看下take方法:

    public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
try {
while (count == 0)
notEmpty.await();//队列空时,在notEmpty条件上等待。
} catch (InterruptedException ie) {
notEmpty.signal(); // 被中断后,唤醒其他等待notEmpty条件的线程。
throw ie;
}
E x = extract();
return x;
} finally {
lock.unlock();
}
}
/**
* 从takeInde的位置取出元素,增加takeIndex,减少count,唤醒在notFull上等待的线程。
* 本方法只有在持有锁的情况下才会被调用。
*/
private E extract() {
final E[] items = this.items;
E x = items[takeIndex];
items[takeIndex] = null;
takeIndex = inc(takeIndex);
--count;
notFull.signal();
return x;
}
  • 其他方法的实现也都比较简单,不进行一一解析。最后注意一下,ArrayBlockingQueue的Iterator是弱一致的。

Jdk1.6 JUC源码解析(12)-ArrayBlockingQueue的更多相关文章

  1. Jdk1.6 JUC源码解析(13)-LinkedBlockingQueue

    功能简介: LinkedBlockingQueue是一种基于单向链表实现的有界的(可选的,不指定默认int最大值)阻塞队列.队列中的元素遵循先入先出 (FIFO)的规则.新元素插入到队列的尾部,从队列 ...

  2. Jdk1.6 JUC源码解析(6)-locks-AbstractQueuedSynchronizer

    功能简介: AbstractQueuedSynchronizer(以下简称AQS)是Java并发包提供的一个同步基础机制,是并发包中实现Lock和其他同步机制(如:Semaphore.CountDow ...

  3. Jdk1.6 JUC源码解析(7)-locks-ReentrantLock

    功能简介: Java代码层面提供的锁机制,可做为Synchronized(jvm内置)的替代物,和Synchronized一样都是可重入的. 与Synchronized相比较而言,ReentrantL ...

  4. Jdk1.6 JUC源码解析(1)-atomic-AtomicXXX

    转自:http://brokendreams.iteye.com/blog/2250109 功能简介: 原子量和普通变量相比,主要体现在读写的线程安全上.对原子量的是原子的(比如多线程下的共享变量i+ ...

  5. 【JUC源码解析】ScheduledThreadPoolExecutor

    简介 它是一个线程池执行器(ThreadPoolExecutor),在给定的延迟(delay)后执行.在多线程或者对灵活性有要求的环境下,要优于java.util.Timer. 提交的任务在执行之前支 ...

  6. 【JUC源码解析】Exchanger

    简介 Exchanger,并发工具类,用于线程间的数据交换. 使用 两个线程,两个缓冲区,一个线程往一个缓冲区里面填数据,另一个线程从另一个缓冲区里面取数据.当填数据的线程将缓冲区填满时,或者取数据的 ...

  7. 【JUC源码解析】SynchronousQueue

    简介 SynchronousQueue是一种特殊的阻塞队列,该队列没有容量. [存数据线程]到达队列后,若发现没有[取数据线程]在此等待,则[存数据线程]便入队等待,直到有[取数据线程]来取数据,并释 ...

  8. 【JUC源码解析】ForkJoinPool

    简介 ForkJoin 框架,另一种风格的线程池(相比于ThreadPoolExecutor),采用分治算法,工作密取策略,极大地提高了并行性.对于那种大任务分割小任务的场景(分治)尤其有用. 框架图 ...

  9. 【JUC源码解析】DelayQueue

    简介 基于优先级队列,以过期时间作为排序的基准,剩余时间最少的元素排在队首.只有过期的元素才能出队,在此之前,线程等待. 源码解析 属性 private final transient Reentra ...

随机推荐

  1. 《连载 | 物联网框架ServerSuperIO教程》- 17.支持实时数据库,高并发保存测点数据。附:3.4 发布与版本更新说明。

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...

  2. 模块化规范Common.js,AMD,CMD

    随着网站规模的不断扩大,嵌入网页中的javascript代码越来越大,开发过程中存在大量问题,如:协同开发,代码复用,大量文件引入,命名冲突,文件依赖. 模块化编程称为迫切的需求. 所谓的模块,就是实 ...

  3. Unity3d在Window上使用SAPI进行语音识别

    前言 在之前<Unity利用Sapi进行windows语音开发>中,本计划不准备继续做语音识别.因为在unity3d中已经提供了语音识别的相关方法,详见unity3d的官方文档:https ...

  4. Error--解决使用Application Loader提交ipa包审核时的报错:ERROR ITMS-90168: "The binary you uploaded was invalid."

    在提交iTunes Connect审核时,使用Application Loader提交ipa包时报错:ERROR ITMS-90168: "The binary you uploaded w ...

  5. Async/Await替代Promise的6个理由

    译者按: Node.js的异步编程方式有效提高了应用性能:然而回调地狱却让人望而生畏,Promise让我们告别回调函数,写出更优雅的异步代码:在实践过程中,却发现Promise并不完美:技术进步是无止 ...

  6. ECP系统J2EE架构开发平台

    一 体系结构 ECP平台是一个基于J2EE架构设计的大型分布式企业协同管理平台,通过采用成熟的J2EE的多层企业架构体系,充分保证了系统的健壮性.开放性和扩展性.可选择部署于多种系统环境,满足不同类型 ...

  7. sublime前端开发工具常用技巧

    ctrl+N//新建文件夹ctrl+shift+p//打开命令行!,ctrl+E//快速生成html模板ctrl+E//自动补齐ctrl+P(#@)//goto 任何地方,其中#查找元素,@查找样式c ...

  8. Ranking Relevance小结

    Ranking Relevance是搜索排序算法的各个影响因子中相当重要的一个部分.对于Ranking Relevance的计算,过去的技术往往分为两个大的方向:Click Behavior和Text ...

  9. vue2 与后台信息交互

    vue-resource  是vue的ajax请求插件 vue-resource文档:https://github.com/vuejs/vue-resource/blob/master/docs/ht ...

  10. Java中的排序方法

    冒泡排序法 快速排序