并发集合6-ArrayBlockingQueue源码分析

1- 前言

ArrayBlockingQueue是基于循环数组实现的有界阻塞队列。不允许元素为null,构造器内必须指定队列的容量。

2- 定义


继承结构和LinkedBlockingQueue一样,在实际使用时可以互换使用。

3- 重要字段

并发集合6-ArrayBlockingQueue源码分析_第1张图片
  1. item:为储存元素的循环数组。
  2. takeIndex:下一次take相关操作的item数组下标。
  3. putIndex:下一次put相关操作的item数组下标。
  4. count:队列元素计数。
并发集合6-ArrayBlockingQueue源码分析_第2张图片

一个ReentrantLock重入锁,两个Condition对象。

4- 构造器

指定初始容量(必须大于0),以及锁的公平性
并发集合6-ArrayBlockingQueue源码分析_第3张图片

调用上面构造器,指定初始容量,默认设置非公平锁


并发集合6-ArrayBlockingQueue源码分析_第4张图片

集合构造器,用ReentrantLock提供锁的语义,实现线程可见性,而不是保证线程安全,因为items、count、putIndex、takeIndex都是普通变量。
并发集合6-ArrayBlockingQueue源码分析_第5张图片

无论使用哪个构造器,都要指定初始大于0的容量,然后立即创建指定容量的Object数组,创建之后,就再也不能更改了,使用的循环数组来实现在不移动数组元素的情况下删除添加元素到数组当中

5- offer方法(不响应中断)

并发集合6-ArrayBlockingQueue源码分析_第6张图片

并发集合6-ArrayBlockingQueue源码分析_第7张图片

加锁入队,保证线程安全,简单判断一下是否队列已满, 如果已满则直接返回false,并不等待,然后将元素加入putIndex位置上,如果putIndex到达数组末尾则直接循环到数组头部,因为容量不变,所以不用担心容量扩容时带来复杂的操作。

6- put方法(响应中断)

并发集合6-ArrayBlockingQueue源码分析_第8张图片

响应中断,并且在在队列满时,需要等待直到被通知notFull。

7- offer(中断超时)

并发集合6-ArrayBlockingQueue源码分析_第9张图片

8- poll(不响应中断)

并发集合6-ArrayBlockingQueue源码分析_第10张图片

并发集合6-ArrayBlockingQueue源码分析_第11张图片

9- take(响应中断)

并发集合6-ArrayBlockingQueue源码分析_第12张图片

10- poll(中断超时)

并发集合6-ArrayBlockingQueue源码分析_第13张图片

11- peek

并发集合6-ArrayBlockingQueue源码分析_第14张图片

12- size

返回当前队列含有的元素数量,强一致性,时间复杂度为O(1)


并发集合6-ArrayBlockingQueue源码分析_第15张图片

13- remove

并发集合6-ArrayBlockingQueue源码分析_第16张图片

并发集合6-ArrayBlockingQueue源码分析_第17张图片

删除第一个在队列中出现的和指定对象相等的元素,时间复杂度为O(n)

14- contains

遍历数组,时间复杂度为O(n)
并发集合6-ArrayBlockingQueue源码分析_第18张图片

15- iterator

此类 iterator() 方法每次返回的 Iterator 是一个“弱一致”的迭代器,从不抛出 ConcurrentModificationException,并且确保可遍历迭代器构造时存在的元素,此外还可能(但并不保证)反映构造后的所有修改。

16- 方法列表

并发集合6-ArrayBlockingQueue源码分析_第19张图片

并发集合6-ArrayBlockingQueue源码分析_第20张图片

总结

  1. 特性基本和LinkedBlockingQueue基本一致,但是基于数组的阻塞队列吞吐量要小于基于链表的阻塞队列。

  2. 和ArrayDeque同样是基于循环数组实现的,在ArrayDeque中是通过与数组长度length-1进行与运算来定位元素位置的,这是因为ArrayDeque是动态扩容的,而在ArrayBlockingQueue中数组是固定容量的,创建后不可更改,当元素下标超过数组长度则直接放在索引为0的位置上,这是因为count计数能保证元素数量不会超出数组的长度,当count等于数组长度时将阻塞put元素的线程直到非空,同样对于take元素也是类似的。

参考链接
http://www.importnew.com/24055.html
http://ifeve.com/juc-arrayblockingqueue/

你可能感兴趣的:(并发集合6-ArrayBlockingQueue源码分析)