一、前言
分析完了ArrayBlockingQueue后,接着分析LinkedBlockingQueue,与ArrayBlockingQueue不相同,LinkedBlockingQueue底层采用的是链表结构,其源码也相对比较简单,下面进行正式的分析。
二、LinkedBlockingQueue数据结构
从LinkedBlockingQueue的命名就大致知道其数据结构采用的是链表结构,通过源码也可以验证我们的猜测,其数据结构如下。
说明:可以看到LinkedBlockingQueue采用的是单链表结构,包含了头结点和尾节点。
三、LinkedBlockingQueue源码分析
3.1 类的继承关系
public class LinkedBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.Serializable {}
说明:LinkedBlockingQueue继承了AbstractQueue抽象类,AbstractQueue定义了对队列的基本操作;同时实现了BlockingQueue接口,BlockingQueue表示阻塞型的队列,其对队列的操作可能会抛出异常;同时也实现了Searializable接口,表示可以被序列化。
3.2 类的内部类
LinkedBlockingQueue内部有一个Node类,表示结点,用于存放元素,其源码如下。
static class Node<E> { // 元素 E item; // next域 Node<E> next; // 构造函数 Node(E x) { item = x; } }
说明:Node类非常简单,包含了两个域,分别用于存放元素和指示下一个结点。
3.3 类的属性
public class LinkedBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.Serializable { // 版本序列号 private static final long serialVersionUID = -6903933977591709194L; // 容量 private final int capacity; // 元素的个数 private final AtomicInteger count = new AtomicInteger(); // 头结点 transient Node<E> head; // 尾结点 private transient Node<E> last; // 取元素锁 private final ReentrantLock takeLock = new ReentrantLock(); // 非空条件 private final Condition notEmpty = takeLock.newCondition(); // 存元素锁 private final ReentrantLock putLock = new ReentrantLock(); // 非满条件 private final Condition notFull = putLock.newCondition(); }