数据结构 - 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();
    }
}

posted @ 2020-04-16 22:18  源码猎人  阅读(210)  评论(0编辑  收藏  举报