(2)offer(E e)方法如果队列满了,则返回false,否则调用insert()方法进行元素的插入,这个方法的源代码如下:
private void insert(E x) {
items[putIndex] = x;
putIndex = inc(putIndex);
++count; // 元素数量加1
notEmpty.signal(); // 唤醒取元素的线程
}
理解如上代码,首先要认识两个变量的含义:takeIndex和putIndex。takeIndex表示下一个被取出元素的索引,putIndex表示下一个被添加元素的索引。它们的定义如下:
int takeIndex; // 下一个被取出元素的索引 int putIndex; // 下一个被添加元素的索引其中inc()的源代码如下:
final int inc(int i) {
return (++i == items.length) 0 : i;
}当i加1后如果队列已经满了,则设置下一个被添加元素的索引为0.
(3) put(E e)方法当加入元素时,如果队列已经满了,则阻塞等待;直到检测到不满时调用insert()方法进行插入。
(4)offer(E e, long timeout, TimeUnit unit) 如果在指定的时间内还无法插入队列,则返回false,表示插入失败。否则让插入队列等待一定的时间。如果插入成功,则返回true。
2、删除元素
public boolean remove(Object o) {
if (o == null) return false;
final Object[] items = this.items;
final ReentrantLock lock = this.lock;
lock.lock();
try {
for (int i = takeIndex, k = count; k > 0; i = inc(i), k--) {
if (o.equals(items[i])) {
removeAt(i);
return true;
}
}
return false;
} finally {
lock.unlock();
}
}
public E poll() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return (count == 0) null : extract();
} finally {
lock.unlock();
}
}
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == 0)
notEmpty.await();
return extract();
} finally {
lock.unlock();
}
}
public E poll(long timeout, TimeUnit unit) throws InterruptedException {
long nanos = unit.toNanos(timeout);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == 0) {
if (nanos <= 0)
return null;
nanos = notEmpty.awaitNanos(nanos);
}
return extract();
} finally {
lock.unlock();
}
}(1)remove(Object o)方法会移除元素值相同的元素。在移除过程中需要使用removeAt()方法,如下:
void removeAt(int i) { // 移除索引处理的元素
final Object[] items = this.items;
// if removing front item, just advance
if (i == takeIndex) {
items[takeIndex] = null;
takeIndex = inc(takeIndex); // 下一个要取出元素的索引
} else {
// slide over all others up through putIndex.
for (;;) {
int nexti = inc(i);
if (nexti != putIndex) {
items[i] = items[nexti];
i = nexti;
} else {
items[i] = null;
putIndex = i;
break;
}
}
}
--count;
notFull.signal(); // 通知生产线程
}
private E extract() {
final Object[] items = this.items;
// 强制将元素转换为泛型E
E x = this.
cast(items[takeIndex]);
// 将第takeIndex元素设为null,即删除。同时,帮助GC回收
items[takeIndex] = null;
// 设置下一个被取出元素的索引
takeIndex = inc(takeIndex);
--count;
notFull.signal();
return x;
}
(3)take()方法调用时,如果此时队列为空,则阻塞等待;否则调用extract()方法返回元素值。
(4)poll(long timeout, TimeUnit unit) 在指定的时间内队列仍然为空则阻塞,超过指定时间返回null;队列不空直接调用extract()方法返回元素值。
3、查找元素
public E peek() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return (count == 0) null : itemAt(takeIndex);
} finally {
lock.unlock();
}
}如果队列为空,则返回null,否则调用itemAt()方法获取元素,如下:
final E itemAt(int i) {
return this.
cast(items[i]);
}
这个类还继承了AbstractQueue中的一个element()方法,如下:
public E element() {
E x = peek();
if (x != null)
return x;
else
throw new NoSuchElementException();
}
调用peek()方法查找,如果元素存在,则返回,否则抛出异常。
4、遍历元素
public Iteratoriterator() { return new Itr(); }
private class Itr implements Iterator{ // 队列中剩余元素的个数 private int remaining; // Number of elements yet to be returned // 下一次调用next()返回的元素的索引 private int nextIndex; // Index of element to be returned by next // 下一次调用next()返回的元素 private E nextItem; // Element to be re