数据结构 - LinkedBlockingDeque 阻塞双向链表队列
简介
LinkedBlockingDeque 是阻塞双向链表队列,它是线程安全的,除了提供两端读写操作外,还具有阻塞功能。内部使用一把锁,在读写操作前必须获取锁,并且每次都是锁整个链表。
LinkedBlockingDeque 类
public class LinkedBlockingDeque<E>
extends AbstractQueue<E>
implements BlockingDeque<E>, java.io.Serializable
继承AbstractQueue抽象类,实现BlockingDeque接口
重要内部类Node
static final class Node<E>
Node 属性
// 元素
E item;
// 上一个元素
Node<E> prev;
// 下一个元素
Node<E> next;
Node 构造函数
Node(E x) {
item = x;
}
LinkedBlockingDeque 属性
// 头节点
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();
LinkedBlockingDeque 构造函数
public LinkedBlockingDeque() {
this(Integer.MAX_VALUE);
}
public LinkedBlockingDeque(int capacity) {
if (capacity <= 0) throw new IllegalArgumentException();
// 设置长度
this.capacity = capacity;
}
public LinkedBlockingDeque(Collection<? extends E> c) {
// 设置长度为Integer最大值
this(Integer.MAX_VALUE);
// 获取锁
final ReentrantLock lock = this.lock;
lock.lock();
try {
// 遍历所有元素
for (E e : c) {
// 有空元素抛异常
if (e == null)
throw new NullPointerException();
// 元素插入链表,满了抛异常
if (!linkLast(new Node<E>(e)))
throw new IllegalStateException("Deque full");
}
} finally {
// 解锁
lock.unlock();
}
}
LinkedBlockingDeque 基础方法
头部插入
private boolean linkFirst(Node<E> node) {
// 长度是否达到最大值
if (count >= capacity)
return false;
// 获取头节点
Node<E> f = first;
// 头节点变为当前下级节点
node.next = f;
// 修改头节点为当前节点
first = node;
// 尾节点为空,尾节点设置为当前节点
if (last == null)
last = node;
else
// 否则原头节点上级设置为当前节点
f.prev = node;
// 元素个数加1
++count;
// 放开读限制
notEmpty.signal();
return true;
}
尾部插入
private boolean linkLast(Node<E> node) {
// 长度超限返回失败
if (count >= capacity)
return false;
// 获取尾节点
Node<E> l = last;
node.prev = l;
// 当前节点设置为尾节点
last = node;
// 头为空,当前节点为头,
// 否则尾节点next指向当前节点
if (first == null)
first = node;
else
l.next = node;
// 元素个数加1
++count;
// 放开读限制
notEmpty.signal();
return true;
}
删除头节点
private E unlinkFirst() {
// 获取头节点
Node<E> f = first;
// 队列为空返回null
if (f == null)
return null;
// 头节点next设置为新头节点
// 原来头节点next指向自身(方便GC)
Node<E> n = f.next;
E item = f.item;
// 原头节点元素置空
f.item = null;
f.next = f;
first = n;
// next为空,设置尾为空
if (n == null)
last = null;
else
// 否则当前next的上一个节点置空
n.prev = null;
// 元素减1
--count;
// 放开插入限制
notFull.signal();
return item;
}
删除尾节点
private E unlinkLast() {
// 获取尾节点
Node<E> l = last;
// 为空返回null
if (l == null)
return null;
// 把尾节点变成孤立节点
// 尾节点上级变为尾节点
Node<E> p = l.prev;
E item = l.item;
l.item = null;
l.prev = l;
last = p;
// prev为空,置空头节点
if (p == null)
first = null;
else
// 否则prev下级节点置空
p.next = null;
// 元素个数减1
--count;
// 放开写限制
notFull.signal();
return item;
}
删除元素
void unlink(Node<E> x) {
// 获取x上级和下级
Node<E> p = x.prev;
Node<E> n = x.next;
// 上级为空说明是头节点
if (p == null) {
unlinkFirst();
} else if (n == null) {
// 下级为空说明是尾节点
unlinkLast();
} else {
// 从链表中删除
p.next = n;
n.prev = p;
// x元素置空(x本身上下级这时还存在)
x.item = null;
// 元素个数减1
--count;
// 放开写限制
notFull.signal();
}
}
LinkedBlockingDeque 添加
满时抛异常
public void addFirst(E e) {
if (!offerFirst(e))
throw new IllegalStateException("Deque full");
}
public void addLast(E e) {
if (!offerLast(e))
throw new IllegalStateException("Deque full");
}
满时返回false
public boolean offerFirst(E e) {
// 为空抛异常
if (e == null) throw new NullPointerException();
// 构建新节点
Node<E> node = new Node<E>(e);
// 获取锁
final ReentrantLock lock = this.lock;
lock.lock();
try {
// 调用linkFirst(往上翻)
return linkFirst(node);
} finally {
// 解锁
lock.unlock();
}
}
public boolean offerLast(E e) {
// 为空抛异常
if (e == null) throw new NullPointerException();
// 构建新节点
Node<E> node = new Node<E>(e);
// 获取锁
final ReentrantLock lock = this.lock;
lock.lock();
try {
// 调用linkLast(往上翻)
return linkLast(node);
} finally {
// 解锁
lock.unlock();
}
}
满时阻塞
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();
}
}
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();
}
}
满时阻塞,超时退出
public boolean offerFirst(E e, long timeout, TimeUnit unit)
throws InterruptedException {
if (e == null) throw new NullPointerException();
Node<E> node = new Node<E>(e);
// 锁定时间
long nanos = unit.toNanos(timeout);
// 获取锁
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
// 满时阻塞,超时重试一次
while (!linkFirst(node)) {
if (nanos <= 0)
// 超时退出
return false;
nanos = notFull.awaitNanos(nanos);
}
return true;
} finally {
// 解锁
lock.unlock();
}
}
public boolean offerLast(E e, long timeout, TimeUnit unit)
throws InterruptedException {
if (e == null) throw new NullPointerException();
Node<E> node = new Node<E>(e);
// 锁定时间
long nanos = unit.toNanos(timeout);
// 获取锁
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
// 满时阻塞,超时重试一次
while (!linkLast(node)) {
if (nanos <= 0)
// 超时退出
return false;
nanos = notFull.awaitNanos(nanos);
}
return true;
} finally {
// 解锁
lock.unlock();
}
}
LinkedBlockingDeque 删除
为空抛异常
public E removeFirst() {
E x = pollFirst();
if (x == null) throw new NoSuchElementException();
return x;
}
public E removeLast() {
E x = pollLast();
if (x == null) throw new NoSuchElementException();
return x;
}
为空返回false
public E pollFirst() {
// 获取锁
final ReentrantLock lock = this.lock;
lock.lock();
try {
// 删除头并返回
return unlinkFirst();
} finally {
// 解锁
lock.unlock();
}
}
public E pollLast() {
// 获取锁
final ReentrantLock lock = this.lock;
lock.lock();
try {
// 删除尾并返回
return unlinkLast();
} finally {
// 解锁
lock.unlock();
}
}
为空阻塞,超时退出
public E pollFirst(long timeout, TimeUnit unit)
throws InterruptedException {
long nanos = unit.toNanos(timeout);
// 获取锁
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
E x;
// 为空阻塞
while ( (x = unlinkFirst()) == null) {
// 超时退出
if (nanos <= 0)
return null;
nanos = notEmpty.awaitNanos(nanos);
}
return x;
} finally {
// 解锁
lock.unlock();
}
}
public E pollLast(long timeout, TimeUnit unit)
throws InterruptedException {
long nanos = unit.toNanos(timeout);
// 获取锁
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
E x;
// 为空阻塞
while ( (x = unlinkLast()) == null) {
// 超时退出
if (nanos <= 0)
return null;
nanos = notEmpty.awaitNanos(nanos);
}
return x;
} finally {
// 解锁
lock.unlock();
}
}
为空阻塞
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();
}
}
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();
}
}
LinkedBlockingDeque 查询
public E getFirst() {
E x = peekFirst();
if (x == null) throw new NoSuchElementException();
return x;
}
public E getLast() {
E x = peekLast();
if (x == null) throw new NoSuchElementException();
return x;
}
public E peekFirst() {
// 获取锁
final ReentrantLock lock = this.lock;
lock.lock();
try {
// 直接读头节点元素
return (first == null) ? null : first.item;
} finally {
// 解锁
lock.unlock();
}
}
public E peekLast() {
// 获取锁
final ReentrantLock lock = this.lock;
lock.lock();
try {
// 直接读尾节点元素
return (last == null) ? null : last.item;
} finally {
// 解锁
lock.unlock();
}
}