ArrayBlockingQueue是阻塞队列中的一个有界队列,当队列满时,再有数据入队列,将会抛出异常。本篇主要介绍该类的相关方法。
该阻塞队列使用可重入锁ReentrantLock实现同步。
一、相关方法
ArrayBlockingQueue(int capacity);
ArrayBlockingQueue(int capacity, boolean fair)
ArrayBlockingQueue(int capacity, boolean fair, Collection<? extends E> c)
这三个方法都是阻塞队列的初始化方法,
capacity:阻塞队列的初始容量
fair:该队列是否是公平队列,默认为非公平,吞吐量高
c:可以将已经存在的列表初始化到阻塞队列中。
public ArrayBlockingQueue(int capacity, boolean fair,
Collection<? extends E> c) {
//this(capacity, fair);
//下面这段代码是把this(capacity, fair);方法中的代码拷贝过来了
if (capacity <= 0)
throw new IllegalArgumentException();
//实际保存数据的也是使用数组保存
this.items = new Object[capacity];
//初始化可重入锁
lock = new ReentrantLock(fair);
//绑定两个condition
notEmpty = lock.newCondition();
notFull = lock.newCondition();
final ReentrantLock lock = this.lock;
lock.lock(); // Lock only for visibility, not mutual exclusion
try {
int i = 0;
try {
for (E e : c) {
//对当前入列的元素判空处理
checkNotNull(e);
items[i++] = e;
}
} catch (ArrayIndexOutOfBoundsException ex) {
throw new IllegalArgumentException();
}
count = i;
putIndex = (i == capacity) ? 0 : i;
} finally {
lock.unlock();
}
}
final int dec(int i)
final E itemAt(int i)
该方法直接获取数组中指定下标的元素,不保证同步
private static void checkNotNull(Object v)
对元素判空,为空抛空指针异常,说明阻塞队列不允许null入列
private void enqueue(E x)
添加元素,并且通过notEmpty唤醒所有等待的线程,相当于唤醒消费者
private void enqueue(E x) {
// assert lock.getHoldCount() == 1;
// assert items[putIndex] == null;
final Object[] items = this.items;
items[putIndex] = x;
if (++putIndex == items.length)
putIndex = 0