package java.util.concurrent
//由数组支持的有界队列
public class ArrayBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable
1、常用方法
构造方法
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);
notEmpty = lock.newCondition();
notFull = lock.newCondition();
}
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();
}
}
父类AbstractQueue实现
/**
* 增加一个元索,如果队列已满,则抛出异常
*/
public boolean add(E e) {
if (offer(e))
return true;
else
throw new IllegalStateException("Queue full");
}
/**
* 移除并返回队列头部的元素,如果队列为空,则抛出异常
*/
public E remove() {
E x = poll();
if (x != null)
return x;
else
throw new NoSuchElementException();
}
/**
* 返回队列头部的元素,如果队列为空,则抛出异常
*/
public E element() {
E x = peek();
if (x != null)
return x;
else
throw new NoSuchElementException();
}
非阻塞方法
/**
* 添加一个元素并返回true,如果队列已满,则返回false
*/
public boolean offer(E e) {
checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (count == items.length)
return false;
else {
enqueue(e);
return true;
}
} finally {
lock.unlock();
}
}
/**
* 移除并返问队列头部的元素,如果队列为空,则返回null
* */
public E poll() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return (count == 0) ? null : dequeue();
} finally {
lock.unlock();
}
}
/**
* 返回队列头部的元素,如果队列为空,则返回null
*/
public E peek() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return itemAt(takeIndex); // null when queue is empty
} finally {
lock.unlock();
}
}
阻塞方法
/**
* 添加一个元素,如果队列满,则阻塞
*/
public void put(E e) throws InterruptedException {
checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == items.length)
notFull.await();
enqueue(e);
} finally {
lock.unlock();
}
}
/**
* 移除并返回队列头部的元素,如果队列为空,则阻塞
*/
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == 0)
notEmpty.await();
return dequeue();
} finally {
lock.unlock();
}
}
其它
/**
* 没有遍历整个队列
*/
public int size() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return count;
} finally {
lock.unlock();
}
}
2、安全性如何保证?
由ReentrantLock(可重入锁)提供。
当队列添加元素后,会调用Condition notEmpty.signal();
而put(E e)方法里会调用notFull.await(); 等待唤醒。
当队列删除元素后,会调用Condition notFull.signal();
而take()方法里会调用notEmpty.await(); 等待唤醒。
3、三个构造方法里其中一个构造方法,构造指定初始化时加入一个集合,加锁的目的?
加锁会保证其可见性,也就是写回主内存。
4、源码中lock.lockInterruptibly();和lock.lock();有何区别?
lockInterruptibly 可被线程中断返回,lock 不能被中断返回。
网友评论