# 并发队列 – 有界阻塞队列 ArrayBlockingQueue 原理探究

#### 二、 ArrayBlockingQueue类图结构

publicArrayBlockingQueue(intcapacity) {

this(capacity, false);

}

publicArrayBlockingQueue(intcapacity, booleanfair) {

if(capacity <= 0)

thrownewIllegalArgumentException();

this.items = newObject[capacity];

lock = newReentrantLock(fair);

notEmpty = lock.newCondition();

notFull = lock.newCondition();

}

#### 三、offer操作

publicbooleanoffer(E e) {

//e为null，则抛出NullPointerException异常

checkNotNull(e);

//获取独占锁

finalReentrantLock lock = this.lock;

lock.lock();

try{

//如果队列满则返回false

if(count == items.length)

returnfalse;

else{

//否者插入元素

insert(e);

returntrue;

}

} finally{

//释放锁

lock.unlock();

}

}

privatevoidinsert(E x) {

//元素入队

items[putIndex] = x;

//计算下一个元素应该存放的下标

putIndex = inc(putIndex);

++count;

notEmpty.signal();

}

//循环队列，计算下标

finalintinc(inti) {

return(++i == items.length) ? 0: i;

}

#### 四、put操作

publicvoidput(E e) throwsInterruptedException {

checkNotNull(e);

finalReentrantLock lock = this.lock;

//获取可被中断锁

lock.lockInterruptibly();

try{

//如果队列满，则把当前线程放入notFull管理的条件队列

while(count == items.length)

notFull.await();

//插入元素

insert(e);

} finally{

lock.unlock();

}

}

#### 五、poll操作

publicE poll() {

finalReentrantLock lock = this.lock;

lock.lock();

try{

//当前队列为空则返回null,否者

return(count == 0) ? null: extract();

} finally{

lock.unlock();

}

}

privateE extract() {

finalObject[] items = this.items;

//获取元素值

E x = this.<E>cast(items[takeIndex]);

//数组中值值为null;

items[takeIndex] = null;

//队头指针计算，队列元素个数减一

takeIndex = inc(takeIndex);

--count;

//发送信号激活notFull条件队列里面的线程

notFull.signal();

returnx;

}

#### 六、take操作

publicE take() throwsInterruptedException {

finalReentrantLock lock = this.lock;

lock.lockInterruptibly();

try{

//队列为空，则等待，直到队列有元素

while(count == 0)

notEmpty.await();

returnextract();

} finally{

lock.unlock();

}

}

#### 七、peek操作

publicE peek() {

finalReentrantLock lock = this.lock;

lock.lock();

try{

//队列为空返回null,否者返回头元素

return(count == 0) ? null: itemAt(takeIndex);

} finally{

lock.unlock();

}

}

finalE itemAt(inti) {

returnthis.<E>cast(items[i]);

}

#### 八、 size操作

publicintsize() {

finalReentrantLock lock = this.lock;

lock.lock();

try{

returncount;

} finally{

lock.unlock();

}

}

113 篇文章27 人订阅

0 条评论