本文主要是介绍【Interview】深入理解阻塞队列之ArrayBlockingQueue,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
概述
ArrayBlockingQueue
是一个由数组构成的有界阻塞队列,此队列按FIFO
(先进先出)原则对元素进行排序,支持公平和非公平模式,默认情况下不保证线程公平的访问队列。新元素插入到队列的尾部,队列获取操作则是从队列头部开始获得元素
常用方法
ArrayBlockingQueue(int capacity)
创建一个固定容量和默认非公司访问策略队列ArrayBlockingQueue(int capacity, boolean fair)
创建一个具有固定容量和指定访问策略的 队列ArrayBlockingQueue(int capacity, boolean fair, Collection<? extends E> c)
创建一个具有固定容量和指定访问策略,并且制定元素类型的 队列boolean add(E e)
插入指定元素到队列尾部,成功返回true,队列已满会直接抛出异常boolean offer(E e)
插入指定元素到队列尾部,成功时返回 true,如果此队列已满,则返回 falseE peek()
获取但不移除此队列的头;如果此队列为空,则返回 nullE poll()
获取并移除此队列的头,如果此队列为空,则返回 nullvoid put(E e)
将指定的元素插入此队列的尾部,如果该队列已满,则等待可用的空间E take()
获取并移除此队列的头部,在元素变得可用之前一直等待
源码阅读
构造函数
/** 存放队列的 */final Object[] items;int takeIndex;int putIndex;int count;/** 可重入锁*/final ReentrantLock lock;private final Condition notEmpty;private final Condition notFull;
ArrayBlockingQueue
的公平模式是使用ReentrantLock
可重入锁实现的。并使用Condition使用队列的阻塞和唤醒
put入队
- put操作比较简单。阻塞的添加。首先判断插入元素是否为空,如果是空则抛出控指针
- 然后获取可重入的排他锁,根据初始化时选择是公平还是非公平模式的锁,加的锁是一个支持可中断的锁。当队列的count等于数组的长度,此时队列已满。则使用
await
的方法是当前线程进入阻塞模式。未满就执行增加元素,并释放锁。
- 队列未满,则添加元素到队列尾巴,当
++putIndex == items.length
条件成立说明此时队列已满,putIndex
赋值为0 从头开始。然后累加队列的总个数,并唤醒一个阻塞的线程
take出队
- 出队的操作也很简单,首先拿到锁,然后判断队列是否为空,为空则进入阻塞等待。不为空则执行
dequeue
出队,并释放锁。
private E dequeue() {//首先获取队列数组final Object[] items = this.items;@SuppressWarnings("unchecked")//拿到出队的元素,临时存储E x = (E) items[takeIndex];//出队的元素置为nullitems[takeIndex] = null;if (++takeIndex == items.length)//当出队元素到队列的最后一个元素,takeIndex还原为0takeIndex = 0;count--;//迭代器操作if (itrs != null)itrs.elementDequeued();//唤醒一个阻塞线程,返回出队的元素notFull.signal();return x;}
这篇关于【Interview】深入理解阻塞队列之ArrayBlockingQueue的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!