JUC-LinkedBlockingDeque Love The Way You Lie 2022-12-20 02:19 135阅读 0赞 和LinkedBlockQueue类似,LinkedBlockingDeque也是一个**基于链表实现的队列**,不过是双端队列,队列双端都可以做插入和移除操作,而且实现的是BlockingDeque接口而不是BlockingQeque接口,当然BlockingDeque还是继承自BlockingQeque。 ### 1. 主要成员 ### 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(); 节点类: static final class Node<E> { E item;// 节点值 Node<E> prev;// 前驱节点 Node<E> next;// 后继节点 Node(E x) { item = x; } } ### 2. 基本操作 ### #### 2.1构造方法 #### public LinkedBlockingDeque() { this(Integer.MAX_VALUE);// 默认容量是整型最大值,链表,无界队列 } public LinkedBlockingDeque(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; } #### 2.2 入队 #### `offer()方法` public boolean offer(E e) { return offerLast(e);// 默认是队尾入队,直接返回入队结果(true/false) } public boolean offerLast(E e) { // offer(e):入队元素e不能是null if (e == null) throw new NullPointerException(); Node<E> node = new Node<E>(e);// 构造节点 final ReentrantLock lock = this.lock; lock.lock(); try { // 尾部入队 return linkLast(node); } finally { lock.unlock(); } } // 尾部入队,直接返回入队结果(true/false) private boolean linkLast(Node<E> node) { 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; } `put()方法` public void put(E e) throws InterruptedException { putLast(e); } public void putLast(E e) throws InterruptedException { // 入队元素同样不能为null if (e == null) throw new NullPointerException(); Node<E> node = new Node<E>(e); final ReentrantLock lock = this.lock; lock.lock(); try { // 和put不同的地方在于,只要添加失败就会一直阻塞 while (!linkLast(node)) notFull.await(); } finally { lock.unlock(); } } `add()` public boolean add(E e) { addLast(e);// 入队失败,直接抛出异常 return true; } public void addLast(E e) { // 入队失败,直接抛出异常 if (!offerLast(e)) throw new IllegalStateException("Deque full"); } #### 2.3 出队 #### `poll()` public E poll() { return pollFirst();// 头部出队 } public E pollFirst() { final ReentrantLock lock = this.lock; lock.lock(); try { // 实际出队方法:unlinkFirst return unlinkFirst(); } finally { lock.unlock(); } } private E unlinkFirst() { // assert lock.isHeldByCurrentThread(); 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; } `remove()` public E remove() { return removeFirst(); } public E removeFirst() { E x = pollFirst(); if (x == null) throw new NoSuchElementException(); return x; } public E pollFirst() { final ReentrantLock lock = this.lock; lock.lock(); try { return unlinkFirst(); } finally { lock.unlock(); } }
还没有评论,来说两句吧...