11

数组阻塞队列(ArrayBlockingQueue)源码解读与分析

 3 years ago
source link: https://my.oschina.net/lishangzhi/blog/4900808
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
数组阻塞队列(ArrayBlockingQueue)源码解读与分析 - 公众号:码农架构 - OSCHINA - 中文开源技术交流社区

生产者消费者模式最核心的部分是生产者与消费者之间的特殊容器,而阻塞队列是特殊容器最常见的实现。JDK中定义了阻塞队列接口BlockingQueue,JDK通过该接口为我们提供了很多种阻塞队列的实现,其中包括本节的主角ArrayBlockingQueue,该类位于java.util.concurrent.ArrayBlockingQueue.java。该类需要实现的核心方法如下,下面我们详细分析ArrayBlockingQueue的实现原理。

format,jpg

从名字可以看出它的存储结构就是一个数组,即基于数组实现了一个FIFO的阻塞队列。新元素都插入到队列尾部,于是最先进入的元素在队列头而最后进入的元素在队列尾部。该数组是有界的,所以构造时需要制定数组的大小。此外,该阻塞队列还提供公平和非公平两种模式。

format,jpg

在分析 ArrayBlockingQueue的实现原理之前我们先通过几个例子来了解它的使用。例子一中我们创建了一个 ArrayBlockingQueue对象,然后通过五个线程去生产数据并put到阻塞队列,二主线程则充当消费端,不断将阻塞队列中的数据取出消费。程序输出如下:

format,jpg

主要展示了阻塞队列空间满了产生阻塞,我们创建一个最大长度为4的阻塞队列,然后通过五个线程分别产生一个数据put到阻塞队列中,但由于阻塞队列最大长度为4,所以在put四个数据后会产生阻塞。

format,jpg

主要展示了阻塞队列为空时产生阻塞,我们创建一个最大长度为10的阻塞队列,然后没有生产者产生数据,却又一个消费者调用take消费数据。由于阻塞队列为空,所以产生了阻塞。

format,jpg

我们先看 ArrayBlockingQueue类的属性和构造函数。其中count变量表示队列的长度大小,takeIndex和putIndex分别表示队列入队和出队的索引,items是一个Object数组用于保存队列的元素,lock是并发控制锁,notEmpty和notFull分别表示队列非空时和非满时的条件。提供两个构造函数,我们在创建时指定队列的大小,另外一个是公平模式参数,默认是非公平的。锁对象使用的是ReentrantLock对象,公平机制也使用的是它的,它的公平机制我们在前面的章节中已经深入分析过了。notEmpty和notFull条件对象通过锁对象的newCondition创建。

format,jpg

put和take方法是阻塞队列的入队和出队方法,它们会间接调用enqueue和dequeue方法。其中put方法会检查入队的元素不能为null,需要先获取锁后才执行enqueue方法维护数组,如果数组长度已经达到最大长度则调用notFull条件的await方法等待。take方法会先获取锁后才执行dequeue方法维护数组,如果数组长度为0则调用notEmpty条件的await方法等待。

format,jpg

offer和poll方法则是支持超时的阻塞队列的入队和出队方法,可以看到主要的区别就在于它们分别调用了notFull和notEmpty条件的awaitNanos方法进行等待。入队时如果超过指定的超时时间则会返回false,表示入队超时导致失败。而出队时如果超过指定的超时时间则会返回null,表示出队超时导致失败。

format,jpg

围绕着JDK中BlockingQueue的其中一种实现,即ArrayBlockingQueue。它的基本结构是使用数组来保存阻塞队列的元素,数组的长度有限制,并且提供了公平和非公平模式。对它的实现原理进行分析,为了方便我们仅保留了ArrayBlockingQueue最核心的源码,只有我们能理解透彻这些内容就已经能掌握它的实现原理了。推荐阅读

format,jpg

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK