这三个都是该类的实例变量,只有一个锁lock,然后lock实例化出两个Condition,notEmpty/noFull分别用来协调多线程的读写操作。
Java代码
[java]
public boolean offer(E e) {
if (e == null) throw new NullPointerException();
final ReentrantLock lock = this.lock;//每个对象对应一个显示的锁
lock.lock();//请求锁直到获得锁(不可以被interrupte)
try {
if (count == items.length)//如果队列已经满了
return false;
else {
insert(e);
return true;
}
} finally {
lock.unlock();//
}
}
看insert方法:
private void insert(E x) {
items[putIndex] = x;
//增加全局index的值。
/*
Inc方法体内部:
final int inc(int i) {
return (++i == items.length) 0 : i;
}
这里可以看出ArrayBlockingQueue采用从前到后向内部数组插入的方式插入新元素的。如果插完了,putIndex可能重新变为0(在已经执行了移除操作的前提下,否则在之前的判断中队列为满)
*/
putIndex = inc(putIndex);
++count;
notEmpty.signal();//wake up one waiting thread
}
Java代码
[java]
public void put(E e) throws InterruptedException {
if (e == null) throw new NullPointerException();
final E[] items = this.items;
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();//请求锁直到得到锁或者变为interrupted
try {
try {
while (count == items.length)//如果满了,当前线程进入noFull对应的等waiting状态
notFull.await();
} catch (InterruptedException ie) {
notFull.signal(); // propagate to non-interrupted thread
throw ie;
}
insert(e);
} finally {
lock.unlock();
}
}
Java代码
[java]
public boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException {
if (e == null) throw new NullPointerException();
long nanos = unit.toNanos(timeout);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
for (;;) {
if (count != items.length) {
insert(e);
return true;
}
if (nanos <= 0)
return false;
try {
//如果没有被 signal/interruptes,需要等待nanos时间才返回
nanos = notFull.awaitNanos(nanos);
} catch (InterruptedException ie) {
notFull.signal(); // propagate to non-interrupted thread
throw ie;
}
}
} finally {
lock.unlock();
}
}
Java代码
[java]
public boolean add(E e) {
return super.add(e);
}
父类:
public boolean add(E e) {
if (offer(e))
return true;
else
throw new IllegalStateException("Queue full");
}
1.2 该类的几个实例变量:takeIndex/putIndex/count
Java代码
[java]
用三个数字来维