前言
LinkedBlockingQueue 是一个基于链表的阻塞队列,其内部维持着一个基于链表的数据队列,其实我们对LinkedBlockingQueue 的API 操作都是间接操作该队列,先看下内部成员变量
成员变量
public class LinkedBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable {
//节点变量
static class Node<E> {
E item;
/**
* One of:
* - the real successor Node
* - this Node, meaning the successor is head.next
* - null, meaning there is no successor (this is the last node)
*/
Node<E> next;
Node(E x) { item = x; }
}
//队列容量,默认Integer.MAX_VALUE
private final int capacity;
//当前队列元素个数
private final AtomicInteger count = new AtomicInteger();
//队列头节点
transient Node<E> head;
//队列尾节点
private transient Node<E> last;
/** Lock held by take, poll, etc */
private final ReentrantLock takeLock = new ReentrantLock();
/** Wait queue for waiting takes */
private final Condition notEmpty = takeLock.newCondition();
/** Lock held by put, offer, etc */
private final ReentrantLock putLock = new ReentrantLock();
/** Wait queue for waiting puts */
private final Condition notFull = putLock.newCondition();
}
从上述可以看出,每个添加到LinkedBlockingQueue 队列的数据都被封装成Node 节点,添加到链表队列中,其中head和last 分别指向队列的头节点和尾节点。与ArrayBlockingQueue 不同的是,LinkedBlockingQueue 内部采用了takeLock 和 putLock 对并发进行控制,也就是说 添加和删除操作并不是互拆操作,可以同时进行,这样也大大提高了吞吐量。如果没有给LinkedBlockingQueue 指定容量大小,默认值Integer.MAX_VALUE 所以 这里 线程池构造的时候 有可能内存溢出。