1- 前言
ArrayBlockingQueue是基于循环数组实现的有界阻塞队列。不允许元素为null,构造器内必须指定队列的容量。
2- 定义
继承结构和LinkedBlockingQueue一样,在实际使用时可以互换使用。
3- 重要字段
- item:为储存元素的循环数组。
- takeIndex:下一次take相关操作的item数组下标。
- putIndex:下一次put相关操作的item数组下标。
- count:队列元素计数。
一个ReentrantLock重入锁,两个Condition对象。
4- 构造器
指定初始容量(必须大于0),以及锁的公平性
调用上面构造器,指定初始容量,默认设置非公平锁
集合构造器,用ReentrantLock提供锁的语义,实现线程可见性,而不是保证线程安全,因为items、count、putIndex、takeIndex都是普通变量。
无论使用哪个构造器,都要指定初始大于0的容量,然后立即创建指定容量的Object数组,创建之后,就再也不能更改了,使用的循环数组来实现在不移动数组元素的情况下删除添加元素到数组当中。
5- offer方法(不响应中断)
加锁入队,保证线程安全,简单判断一下是否队列已满,如果已满则直接返回false,并不等待,然后将元素加入putIndex位置上,如果putIndex到达数组末尾则直接循环到数组头部,因为容量不变,所以不用担心容量扩容时带来复杂的操作。
6- put方法(响应中断)
响应中断,并且在在队列满时,需要等待直到被通知notFull。
7- offer(中断超时)
8- poll(不响应中断)
9- take(响应中断)
10- poll(中断超时)
11- peek
12- size
返回当前队列含有的元素数量,强一致性,时间复杂度为O(1)
13- remove
删除第一个在队列中出现的和指定对象相等的元素,时间复杂度为O(n)
14- contains
遍历数组,时间复杂度为O(n)
15- iterator
此类 iterator() 方法每次返回的 Iterator 是一个“弱一致”的迭代器,从不抛出 ConcurrentModificationException,并且确保可遍历迭代器构造时存在的元素,此外还可能(但并不保证)反映构造后的所有修改。
16- 方法列表
总结
特性基本和LinkedBlockingQueue基本一致,但是基于数组的阻塞队列吞吐量要小于基于链表的阻塞队列。
和ArrayDeque同样是基于循环数组实现的,在ArrayDeque中是通过与数组长度length-1进行与运算来定位元素位置的,这是因为ArrayDeque是动态扩容的,而在ArrayBlockingQueue中数组是固定容量的,创建后不可更改,当元素下标超过数组长度则直接放在索引为0的位置上,这是因为count计数能保证元素数量不会超出数组的长度,当count等于数组长度时将阻塞put元素的线程直到非空,同样对于take元素也是类似的。
参考链接
http://www.importnew.com/24055.html
http://ifeve.com/juc-arrayblockingqueue/