1、BlockingQueue 介绍
在所有的并发容器中,BlockingQueue是最常见的一种。BlockingQueue是一个带阻塞功能的队
列,当入队列时,若队列已满,则阻塞调用者;当出队列时,若队列为空,则阻塞调用者。
在Concurrent包中,BlockingQueue是一个接口,有许多个不同的实现类,如图所示
该接口的定义如下:
public interface BlockingQueue<E> extends Queue<E> {
//...
boolean add(E e);
boolean offer(E e);
void put(E e) throws InterruptedException;
boolean remove(Object o);
E take() throws InterruptedException;
E poll(long timeout, TimeUnit unit) throws InterruptedException;
//...
}
该接口和JDK集合中的Queue接口是兼容的,同时在其基础上增加了阻塞功能。在这里,入队提供了add(…)、offer(…)、put(…)3个方法,有什么区别呢?
从上面的定义可以看到,add(…)和offer(…)的返回值是boolean,而put(…)无返回值,还会抛出异常,所以add(…)和offer(…)是无阻塞的,也是Queue本身定义的接口,而put(…)是阻塞的。add(…)和offer(…)的区别不大,当队列为满的时候,前者会抛出异常,后者则直接返回false。
出队列与之类似,提供了remove()、poll()、take() 等方法,remove() 是非阻塞式的,take() 和 poll()是阻塞式的。
2、ArrayBlockingQueue
ArrayBlockingQueue是一个用数组实现的环形队列,在构造方法中,会要求传入数组的容量。
public ArrayBlockingQueue(int capacity) {
this(capacity, false);
}
public ArrayBlockingQueue(int capacity, boolean fair) {
// ...
}
public ArrayBlockingQueue(int capacity, boolean fair, Collection<? extends E> c) {
this(capacity, fair);
// ...
}
其核心数据结构如下:
public class ArrayBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.Serializable {
//...
final Object[] items;
// 队头指针
int takeIndex;
// 队尾指针
int putIndex;
int count;
// 核心为1个锁外加两个条件
final ReentrantLock lock;
private final Condition notEmpty;
private final Condition notFull;
//...
}
其put/take方法 也很简单,如下所示。
put方法: