LinkedBlockingDeque是一个线程安全的双向并发阻塞队列,同时支持FIFO(先进先出)和FILO(先进后出)两种模式,并且为防止数据无限膨胀,可以设置阻塞队列的容量,默认不设置的话容量大小为Integer.MAX_VALUE
// 双向链表头结点
transient Node<E> first;
// 双向链表尾节点
transient Node<E> last;
// 当前队列的数据总数
private transient int count;
// 队列的容量
private final int capacity;
// 读写锁
final ReentrantLock lock = new ReentrantLock();
// 读取数据线程等待条件
private final Condition notEmpty = lock.newCondition();
// 写入数据线程等待条件
private final Condition notFull = lock.newCondition();
Node类定义
static final class Node<E> {
// 链表元素
E item;
// 当前节点的前一个节点
Node<E> prev;
// 当前节点的后一个节点
Node<E> next;
Node(E x) {
item = x;
}
}
只是设置一下容量,并无过多操作
public LinkedBlockingDeque() {
this(Integer.MAX_VALUE);
}
public LinkedBlockingDeque(int capacity) {
if (capacity <= 0) throw new IllegalArgumentException();
this.capacity = capacity;
}
public void putFirst(E e) throws InterruptedException {
// 不允许插入空数据
if (e == null) throw new NullPointerException();
// 构造插入节点
Node<E> node = new Node<E>(e);
// 获取读写锁并加锁
final ReentrantLock lock = this.lock;
lock.lock();
try {
// 将元素添加到队列头,如果队列已满则会一直等待
while (!linkFirst(node))
notFull.await();
} finally {
lock.unlock();
}
}
private boolean linkFirst(Node<E> node) {
// 队列当前元素数大于等于队列容量直接返回false
if (count >= capacity)
return false;
// 获取头节点的引用
Node<E> f = first;
// 将当前节点的后节点设置为旧的头节点
node.next = f;
// 将头结点的引用指向当前节点
first = node;
// 尾节点为null表示队列只有一个元素,头尾节点指向当前节点
if (last == null)
last = node;
else
// 设置旧的头结点前一个节点为当前节点
f.prev = node;
// 队列元素数量加一
++count;
// 唤醒正在阻塞的读取队列的线程
notEmpty.signal();
return true;
}
public void putLast(E e) throws InterruptedException {
if (e == null) throw new NullPointerException();
Node<E> node = new Node<E>(e);
final ReentrantLock lock = this.lock;
lock.lock();
try {
while (!linkLast(node))
notFull.await();
} finally {
lock.unlock();
}
}
private boolean linkLast(Node<E> node) {
// 当前队列容量已满则直接返回false
if (count >= capacity)
return false;
// 获取双向链表的原有的尾节点
Node<E> l = last;
// 设置当前节点的前一节点为原有的尾节点
node.prev = l;
// 设置尾节点引用为当前节点
last = node;
// 如果头节点为空,则表示当前节点为第一个节点,这只头节点和尾节点指向同一节点
if (first == null)
first = node;
else
// 设置原有尾节点的下一节点为当前节点
l.next = node;
// 当前队列数量加一
++count;
// 唤醒正在阻塞的读取队列的线程
notEmpty.signal();
return true;
}
public E takeFirst() throws InterruptedException {
// 获取读写锁并加锁
final ReentrantLock lock = this.lock;
lock.lock();
try {
E x;
// 从双向链表头部取出元素,如果为空则一直等待
while ( (x = unlinkFirst()) == null)
notEmpty.await();
return x;
} finally {
lock.unlock();
}
}
private E unlinkFirst() {
// 获取双向链表头结点,如果为空直接返回
Node<E> f = first;
if (f == null)
return null;
// 获取头节点的下一节点,做新的头结点
Node<E> n = f.next;
// 获取目前头节点的元素
E item = f.item;
// 将目前头结点元素置空
f.item = null;
// 设置头节点的下一节点引用为自己
f.next = f; // help GC
// 设置新的头结点
first = n;
// 如果新的头结点为空则队列为空,设置尾节点也为空
if (n == null)
last = null;
else
// 否则设置新的头节点的前一节点为空
n.prev = null;
// 当前队列的数量减一
--count;
// 唤醒等待写入队列的线程
notFull.signal();
return item;
}
public E takeLast() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lock();
try {
E x;
while ( (x = unlinkLast()) == null)
notEmpty.await();
return x;
} finally {
lock.unlock();
}
}
private E unlinkLast() {
// 获取尾节点,如果为空则直接返回
Node<E> l = last;
if (l == null)
return null;
// 获取尾节点的前一节点,做新的尾节点
Node<E> p = l.prev;
// 获取当前尾节点的元素
E item = l.item;
// 将当前尾节点的元素置空
l.item = null;
l.prev = l; // help GC
// 设置新的尾节点
last = p;
// 如果新的尾节点为空表示队列为空,则头节点也为空
if (p == null)
first = null;
else
// 设置新的尾节点的下一节点为空
p.next = null;
// 队列总数减一
--count;
// 唤醒等待写入队列的线程
notFull.signal();
return item;
}
public Iterator<E> iterator() {
return new Itr();
}
private class Itr extends AbstractItr {
Node<E> firstNode() { return first; }
Node<E> nextNode(Node<E> n) { return n.next; }
}
AbstractItr 类实现
private abstract class AbstractItr implements Iterator<E> {
// next下一次调用返回的节点
Node<E> next;
// next下一次调用返回的元素
E nextItem;
// 上一个调用next返回的节点
private Node<E> lastRet;
// 获取头节点抽象方法
abstract Node<E> firstNode();
// 获取下一节点抽象方法
abstract Node<E> nextNode(Node<E> n);
AbstractItr() {
// 获取当前队列的读写锁
final ReentrantLock lock = LinkedBlockingDeque.this.lock;
lock.lock();
try {
// 设置下一个next调用节点为头节点
next = firstNode();
// 设置下一个next调用返回元素
nextItem = (next == null) ? null : next.item;
} finally {
lock.unlock();
}
}
// 获取链表的下一个节点
private Node<E> succ(Node<E> n) {
// Chains of deleted nodes ending in null or self-links
// are possible if multiple interior nodes are removed.
for (;;) {
Node<E> s = nextNode(n);
if (s == null)
return null;
else if (s.item != null)
return s;
else if (s == n)
return firstNode();
else
n = s;
}
}
// 更新next 和 nextItem
void advance() {
final ReentrantLock lock = LinkedBlockingDeque.this.lock;
lock.lock();
try {
// assert next != null;
next = succ(next);
nextItem = (next == null) ? null : next.item;
} finally {
lock.unlock();
}
}
public boolean hasNext() {
return next != null;
}
// 返回节点元素
public E next() {
if (next == null)
throw new NoSuchElementException();
lastRet = next;
E x = nextItem;
advance();
return x;
}
// 删除元素
public void remove() {
Node<E> n = lastRet;
if (n == null)
throw new IllegalStateException();
lastRet = null;
final ReentrantLock lock = LinkedBlockingDeque.this.lock;
lock.lock();
try {
if (n.item != null)
unlink(n);
} finally {
lock.unlock();
}
}
}