构造器
===
使用ArrayBlockingQueue的时候,必须指定一个capacity阻塞队列的容量。可以传入可选的fair值,以采取不同公平性策略,默认使用非公平的策略。另外,可以传入集合对象,直接构造阻塞队列。
// 必须指定容量, 默认采用非公平策略
public ArrayBlockingQueue(int capacity) {
this(capacity, false);
}
// 另外,可指定公平性策略
public ArrayBlockingQueue(int capacity, boolean fair) {
// 对容量进行简单校验
if (capacity <= 0)
throw new IllegalArgumentException();
this.items = new Object[capacity]; // 初始化底层数组
lock = new ReentrantLock(fair); // 初始化lock
notEmpty = lock.newCondition(); // 初始化条件变量notEmpty
notFull = lock.newCondition(); // 初始化条件变量notFull
}
// 另外,可指定传入集合直接构造
public ArrayBlockingQueue(int capacity, boolean fair,
Collection<? extends E> c) {
this(capacity, fair);
// 加锁只是为了可见性, 而不是为了互斥特性
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();
}
}
出队和入队操作
=======
队列的操作最核心的部分莫过于入队和出队了,后面分析的方法基本上都基于这两个工具方法。
入队enqueue
=========
private void enqueue(E x) {
// assert lock.getHoldCount() == 1;
// assert items[putIndex] == null;
final Object[] items = this.items;
// 把元素x放入数组
items[putIndex] = x;
// 下一个元素应该存放的下标位置
if (++putIndex == items.length)
putIn