Home | History | Annotate | Download | only in concurrent
      1 /*
      2  * Written by Doug Lea with assistance from members of JCP JSR-166
      3  * Expert Group and released to the public domain, as explained at
      4  * http://creativecommons.org/licenses/publicdomain
      5  */
      6 
      7 package java.util.concurrent;
      8 
      9 import java.util.AbstractQueue;
     10 import java.util.Collection;
     11 import java.util.Iterator;
     12 import java.util.NoSuchElementException;
     13 import java.util.concurrent.locks.Condition;
     14 import java.util.concurrent.locks.ReentrantLock;
     15 
     16 /**
     17  * An optionally-bounded {@linkplain BlockingDeque blocking deque} based on
     18  * linked nodes.
     19  *
     20  * <p> The optional capacity bound constructor argument serves as a
     21  * way to prevent excessive expansion. The capacity, if unspecified,
     22  * is equal to {@link Integer#MAX_VALUE}.  Linked nodes are
     23  * dynamically created upon each insertion unless this would bring the
     24  * deque above capacity.
     25  *
     26  * <p>Most operations run in constant time (ignoring time spent
     27  * blocking).  Exceptions include {@link #remove(Object) remove},
     28  * {@link #removeFirstOccurrence removeFirstOccurrence}, {@link
     29  * #removeLastOccurrence removeLastOccurrence}, {@link #contains
     30  * contains}, {@link #iterator iterator.remove()}, and the bulk
     31  * operations, all of which run in linear time.
     32  *
     33  * <p>This class and its iterator implement all of the
     34  * <em>optional</em> methods of the {@link Collection} and {@link
     35  * Iterator} interfaces.
     36  *
     37  * <p>This class is a member of the
     38  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
     39  * Java Collections Framework</a>.
     40  *
     41  * @since 1.6
     42  * @author  Doug Lea
     43  * @param <E> the type of elements held in this collection
     44  */
     45 public class LinkedBlockingDeque<E>
     46     extends AbstractQueue<E>
     47     implements BlockingDeque<E>,  java.io.Serializable {
     48 
     49     /*
     50      * Implemented as a simple doubly-linked list protected by a
     51      * single lock and using conditions to manage blocking.
     52      *
     53      * To implement weakly consistent iterators, it appears we need to
     54      * keep all Nodes GC-reachable from a predecessor dequeued Node.
     55      * That would cause two problems:
     56      * - allow a rogue Iterator to cause unbounded memory retention
     57      * - cause cross-generational linking of old Nodes to new Nodes if
     58      *   a Node was tenured while live, which generational GCs have a
     59      *   hard time dealing with, causing repeated major collections.
     60      * However, only non-deleted Nodes need to be reachable from
     61      * dequeued Nodes, and reachability does not necessarily have to
     62      * be of the kind understood by the GC.  We use the trick of
     63      * linking a Node that has just been dequeued to itself.  Such a
     64      * self-link implicitly means to jump to "first" (for next links)
     65      * or "last" (for prev links).
     66      */
     67 
     68     /*
     69      * We have "diamond" multiple interface/abstract class inheritance
     70      * here, and that introduces ambiguities. Often we want the
     71      * BlockingDeque javadoc combined with the AbstractQueue
     72      * implementation, so a lot of method specs are duplicated here.
     73      */
     74 
     75     private static final long serialVersionUID = -387911632671998426L;
     76 
     77     /** Doubly-linked list node class */
     78     static final class Node<E> {
     79         /**
     80          * The item, or null if this node has been removed.
     81          */
     82         E item;
     83 
     84         /**
     85          * One of:
     86          * - the real predecessor Node
     87          * - this Node, meaning the predecessor is tail
     88          * - null, meaning there is no predecessor
     89          */
     90         Node<E> prev;
     91 
     92         /**
     93          * One of:
     94          * - the real successor Node
     95          * - this Node, meaning the successor is head
     96          * - null, meaning there is no successor
     97          */
     98         Node<E> next;
     99 
    100         Node(E x, Node<E> p, Node<E> n) {
    101             item = x;
    102             prev = p;
    103             next = n;
    104         }
    105     }
    106 
    107     /**
    108      * Pointer to first node.
    109      * Invariant: (first == null && last == null) ||
    110      *            (first.prev == null && first.item != null)
    111      */
    112     transient Node<E> first;
    113 
    114     /**
    115      * Pointer to last node.
    116      * Invariant: (first == null && last == null) ||
    117      *            (last.next == null && last.item != null)
    118      */
    119     transient Node<E> last;
    120 
    121     /** Number of items in the deque */
    122     private transient int count;
    123 
    124     /** Maximum number of items in the deque */
    125     private final int capacity;
    126 
    127     /** Main lock guarding all access */
    128     final ReentrantLock lock = new ReentrantLock();
    129 
    130     /** Condition for waiting takes */
    131     private final Condition notEmpty = lock.newCondition();
    132 
    133     /** Condition for waiting puts */
    134     private final Condition notFull = lock.newCondition();
    135 
    136     /**
    137      * Creates a {@code LinkedBlockingDeque} with a capacity of
    138      * {@link Integer#MAX_VALUE}.
    139      */
    140     public LinkedBlockingDeque() {
    141         this(Integer.MAX_VALUE);
    142     }
    143 
    144     /**
    145      * Creates a {@code LinkedBlockingDeque} with the given (fixed) capacity.
    146      *
    147      * @param capacity the capacity of this deque
    148      * @throws IllegalArgumentException if {@code capacity} is less than 1
    149      */
    150     public LinkedBlockingDeque(int capacity) {
    151         if (capacity <= 0) throw new IllegalArgumentException();
    152         this.capacity = capacity;
    153     }
    154 
    155     /**
    156      * Creates a {@code LinkedBlockingDeque} with a capacity of
    157      * {@link Integer#MAX_VALUE}, initially containing the elements of
    158      * the given collection, added in traversal order of the
    159      * collection's iterator.
    160      *
    161      * @param c the collection of elements to initially contain
    162      * @throws NullPointerException if the specified collection or any
    163      *         of its elements are null
    164      */
    165     public LinkedBlockingDeque(Collection<? extends E> c) {
    166         this(Integer.MAX_VALUE);
    167         final ReentrantLock lock = this.lock;
    168         lock.lock(); // Never contended, but necessary for visibility
    169         try {
    170             for (E e : c) {
    171                 if (e == null)
    172                     throw new NullPointerException();
    173                 if (!linkLast(e))
    174                     throw new IllegalStateException("Deque full");
    175             }
    176         } finally {
    177             lock.unlock();
    178         }
    179     }
    180 
    181 
    182     // Basic linking and unlinking operations, called only while holding lock
    183 
    184     /**
    185      * Links e as first element, or returns false if full.
    186      */
    187     private boolean linkFirst(E e) {
    188         // assert lock.isHeldByCurrentThread();
    189         if (count >= capacity)
    190             return false;
    191         Node<E> f = first;
    192         Node<E> x = new Node<E>(e, null, f);
    193         first = x;
    194         if (last == null)
    195             last = x;
    196         else
    197             f.prev = x;
    198         ++count;
    199         notEmpty.signal();
    200         return true;
    201     }
    202 
    203     /**
    204      * Links e as last element, or returns false if full.
    205      */
    206     private boolean linkLast(E e) {
    207         // assert lock.isHeldByCurrentThread();
    208         if (count >= capacity)
    209             return false;
    210         Node<E> l = last;
    211         Node<E> x = new Node<E>(e, l, null);
    212         last = x;
    213         if (first == null)
    214             first = x;
    215         else
    216             l.next = x;
    217         ++count;
    218         notEmpty.signal();
    219         return true;
    220     }
    221 
    222     /**
    223      * Removes and returns first element, or null if empty.
    224      */
    225     private E unlinkFirst() {
    226         // assert lock.isHeldByCurrentThread();
    227         Node<E> f = first;
    228         if (f == null)
    229             return null;
    230         Node<E> n = f.next;
    231         E item = f.item;
    232         f.item = null;
    233         f.next = f; // help GC
    234         first = n;
    235         if (n == null)
    236             last = null;
    237         else
    238             n.prev = null;
    239         --count;
    240         notFull.signal();
    241         return item;
    242     }
    243 
    244     /**
    245      * Removes and returns last element, or null if empty.
    246      */
    247     private E unlinkLast() {
    248         // assert lock.isHeldByCurrentThread();
    249         Node<E> l = last;
    250         if (l == null)
    251             return null;
    252         Node<E> p = l.prev;
    253         E item = l.item;
    254         l.item = null;
    255         l.prev = l; // help GC
    256         last = p;
    257         if (p == null)
    258             first = null;
    259         else
    260             p.next = null;
    261         --count;
    262         notFull.signal();
    263         return item;
    264     }
    265 
    266     /**
    267      * Unlinks x.
    268      */
    269     void unlink(Node<E> x) {
    270         // assert lock.isHeldByCurrentThread();
    271         Node<E> p = x.prev;
    272         Node<E> n = x.next;
    273         if (p == null) {
    274             unlinkFirst();
    275         } else if (n == null) {
    276             unlinkLast();
    277         } else {
    278             p.next = n;
    279             n.prev = p;
    280             x.item = null;
    281             // Don't mess with x's links.  They may still be in use by
    282             // an iterator.
    283             --count;
    284             notFull.signal();
    285         }
    286     }
    287 
    288     // BlockingDeque methods
    289 
    290     /**
    291      * @throws IllegalStateException {@inheritDoc}
    292      * @throws NullPointerException  {@inheritDoc}
    293      */
    294     public void addFirst(E e) {
    295         if (!offerFirst(e))
    296             throw new IllegalStateException("Deque full");
    297     }
    298 
    299     /**
    300      * @throws IllegalStateException {@inheritDoc}
    301      * @throws NullPointerException  {@inheritDoc}
    302      */
    303     public void addLast(E e) {
    304         if (!offerLast(e))
    305             throw new IllegalStateException("Deque full");
    306     }
    307 
    308     /**
    309      * @throws NullPointerException {@inheritDoc}
    310      */
    311     public boolean offerFirst(E e) {
    312         if (e == null) throw new NullPointerException();
    313         final ReentrantLock lock = this.lock;
    314         lock.lock();
    315         try {
    316             return linkFirst(e);
    317         } finally {
    318             lock.unlock();
    319         }
    320     }
    321 
    322     /**
    323      * @throws NullPointerException {@inheritDoc}
    324      */
    325     public boolean offerLast(E e) {
    326         if (e == null) throw new NullPointerException();
    327         final ReentrantLock lock = this.lock;
    328         lock.lock();
    329         try {
    330             return linkLast(e);
    331         } finally {
    332             lock.unlock();
    333         }
    334     }
    335 
    336     /**
    337      * @throws NullPointerException {@inheritDoc}
    338      * @throws InterruptedException {@inheritDoc}
    339      */
    340     public void putFirst(E e) throws InterruptedException {
    341         if (e == null) throw new NullPointerException();
    342         final ReentrantLock lock = this.lock;
    343         lock.lock();
    344         try {
    345             while (!linkFirst(e))
    346                 notFull.await();
    347         } finally {
    348             lock.unlock();
    349         }
    350     }
    351 
    352     /**
    353      * @throws NullPointerException {@inheritDoc}
    354      * @throws InterruptedException {@inheritDoc}
    355      */
    356     public void putLast(E e) throws InterruptedException {
    357         if (e == null) throw new NullPointerException();
    358         final ReentrantLock lock = this.lock;
    359         lock.lock();
    360         try {
    361             while (!linkLast(e))
    362                 notFull.await();
    363         } finally {
    364             lock.unlock();
    365         }
    366     }
    367 
    368     /**
    369      * @throws NullPointerException {@inheritDoc}
    370      * @throws InterruptedException {@inheritDoc}
    371      */
    372     public boolean offerFirst(E e, long timeout, TimeUnit unit)
    373         throws InterruptedException {
    374         if (e == null) throw new NullPointerException();
    375         long nanos = unit.toNanos(timeout);
    376         final ReentrantLock lock = this.lock;
    377         lock.lockInterruptibly();
    378         try {
    379             while (!linkFirst(e)) {
    380                 if (nanos <= 0)
    381                     return false;
    382                 nanos = notFull.awaitNanos(nanos);
    383             }
    384             return true;
    385         } finally {
    386             lock.unlock();
    387         }
    388     }
    389 
    390     /**
    391      * @throws NullPointerException {@inheritDoc}
    392      * @throws InterruptedException {@inheritDoc}
    393      */
    394     public boolean offerLast(E e, long timeout, TimeUnit unit)
    395         throws InterruptedException {
    396         if (e == null) throw new NullPointerException();
    397         long nanos = unit.toNanos(timeout);
    398         final ReentrantLock lock = this.lock;
    399         lock.lockInterruptibly();
    400         try {
    401             while (!linkLast(e)) {
    402                 if (nanos <= 0)
    403                     return false;
    404                 nanos = notFull.awaitNanos(nanos);
    405             }
    406             return true;
    407         } finally {
    408             lock.unlock();
    409         }
    410     }
    411 
    412     /**
    413      * @throws NoSuchElementException {@inheritDoc}
    414      */
    415     public E removeFirst() {
    416         E x = pollFirst();
    417         if (x == null) throw new NoSuchElementException();
    418         return x;
    419     }
    420 
    421     /**
    422      * @throws NoSuchElementException {@inheritDoc}
    423      */
    424     public E removeLast() {
    425         E x = pollLast();
    426         if (x == null) throw new NoSuchElementException();
    427         return x;
    428     }
    429 
    430     public E pollFirst() {
    431         final ReentrantLock lock = this.lock;
    432         lock.lock();
    433         try {
    434             return unlinkFirst();
    435         } finally {
    436             lock.unlock();
    437         }
    438     }
    439 
    440     public E pollLast() {
    441         final ReentrantLock lock = this.lock;
    442         lock.lock();
    443         try {
    444             return unlinkLast();
    445         } finally {
    446             lock.unlock();
    447         }
    448     }
    449 
    450     public E takeFirst() throws InterruptedException {
    451         final ReentrantLock lock = this.lock;
    452         lock.lock();
    453         try {
    454             E x;
    455             while ( (x = unlinkFirst()) == null)
    456                 notEmpty.await();
    457             return x;
    458         } finally {
    459             lock.unlock();
    460         }
    461     }
    462 
    463     public E takeLast() throws InterruptedException {
    464         final ReentrantLock lock = this.lock;
    465         lock.lock();
    466         try {
    467             E x;
    468             while ( (x = unlinkLast()) == null)
    469                 notEmpty.await();
    470             return x;
    471         } finally {
    472             lock.unlock();
    473         }
    474     }
    475 
    476     public E pollFirst(long timeout, TimeUnit unit)
    477         throws InterruptedException {
    478         long nanos = unit.toNanos(timeout);
    479         final ReentrantLock lock = this.lock;
    480         lock.lockInterruptibly();
    481         try {
    482             E x;
    483             while ( (x = unlinkFirst()) == null) {
    484                 if (nanos <= 0)
    485                     return null;
    486                 nanos = notEmpty.awaitNanos(nanos);
    487             }
    488             return x;
    489         } finally {
    490             lock.unlock();
    491         }
    492     }
    493 
    494     public E pollLast(long timeout, TimeUnit unit)
    495         throws InterruptedException {
    496         long nanos = unit.toNanos(timeout);
    497         final ReentrantLock lock = this.lock;
    498         lock.lockInterruptibly();
    499         try {
    500             E x;
    501             while ( (x = unlinkLast()) == null) {
    502                 if (nanos <= 0)
    503                     return null;
    504                 nanos = notEmpty.awaitNanos(nanos);
    505             }
    506             return x;
    507         } finally {
    508             lock.unlock();
    509         }
    510     }
    511 
    512     /**
    513      * @throws NoSuchElementException {@inheritDoc}
    514      */
    515     public E getFirst() {
    516         E x = peekFirst();
    517         if (x == null) throw new NoSuchElementException();
    518         return x;
    519     }
    520 
    521     /**
    522      * @throws NoSuchElementException {@inheritDoc}
    523      */
    524     public E getLast() {
    525         E x = peekLast();
    526         if (x == null) throw new NoSuchElementException();
    527         return x;
    528     }
    529 
    530     public E peekFirst() {
    531         final ReentrantLock lock = this.lock;
    532         lock.lock();
    533         try {
    534             return (first == null) ? null : first.item;
    535         } finally {
    536             lock.unlock();
    537         }
    538     }
    539 
    540     public E peekLast() {
    541         final ReentrantLock lock = this.lock;
    542         lock.lock();
    543         try {
    544             return (last == null) ? null : last.item;
    545         } finally {
    546             lock.unlock();
    547         }
    548     }
    549 
    550     public boolean removeFirstOccurrence(Object o) {
    551         if (o == null) return false;
    552         final ReentrantLock lock = this.lock;
    553         lock.lock();
    554         try {
    555             for (Node<E> p = first; p != null; p = p.next) {
    556                 if (o.equals(p.item)) {
    557                     unlink(p);
    558                     return true;
    559                 }
    560             }
    561             return false;
    562         } finally {
    563             lock.unlock();
    564         }
    565     }
    566 
    567     public boolean removeLastOccurrence(Object o) {
    568         if (o == null) return false;
    569         final ReentrantLock lock = this.lock;
    570         lock.lock();
    571         try {
    572             for (Node<E> p = last; p != null; p = p.prev) {
    573                 if (o.equals(p.item)) {
    574                     unlink(p);
    575                     return true;
    576                 }
    577             }
    578             return false;
    579         } finally {
    580             lock.unlock();
    581         }
    582     }
    583 
    584     // BlockingQueue methods
    585 
    586     /**
    587      * Inserts the specified element at the end of this deque unless it would
    588      * violate capacity restrictions.  When using a capacity-restricted deque,
    589      * it is generally preferable to use method {@link #offer(E) offer}.
    590      *
    591      * <p>This method is equivalent to {@link #addLast}.
    592      *
    593      * @throws IllegalStateException if the element cannot be added at this
    594      *         time due to capacity restrictions
    595      * @throws NullPointerException if the specified element is null
    596      */
    597     public boolean add(E e) {
    598         addLast(e);
    599         return true;
    600     }
    601 
    602     /**
    603      * @throws NullPointerException if the specified element is null
    604      */
    605     public boolean offer(E e) {
    606         return offerLast(e);
    607     }
    608 
    609     /**
    610      * @throws NullPointerException {@inheritDoc}
    611      * @throws InterruptedException {@inheritDoc}
    612      */
    613     public void put(E e) throws InterruptedException {
    614         putLast(e);
    615     }
    616 
    617     /**
    618      * @throws NullPointerException {@inheritDoc}
    619      * @throws InterruptedException {@inheritDoc}
    620      */
    621     public boolean offer(E e, long timeout, TimeUnit unit)
    622         throws InterruptedException {
    623         return offerLast(e, timeout, unit);
    624     }
    625 
    626     /**
    627      * Retrieves and removes the head of the queue represented by this deque.
    628      * This method differs from {@link #poll poll} only in that it throws an
    629      * exception if this deque is empty.
    630      *
    631      * <p>This method is equivalent to {@link #removeFirst() removeFirst}.
    632      *
    633      * @return the head of the queue represented by this deque
    634      * @throws NoSuchElementException if this deque is empty
    635      */
    636     public E remove() {
    637         return removeFirst();
    638     }
    639 
    640     public E poll() {
    641         return pollFirst();
    642     }
    643 
    644     public E take() throws InterruptedException {
    645         return takeFirst();
    646     }
    647 
    648     public E poll(long timeout, TimeUnit unit) throws InterruptedException {
    649         return pollFirst(timeout, unit);
    650     }
    651 
    652     /**
    653      * Retrieves, but does not remove, the head of the queue represented by
    654      * this deque.  This method differs from {@link #peek peek} only in that
    655      * it throws an exception if this deque is empty.
    656      *
    657      * <p>This method is equivalent to {@link #getFirst() getFirst}.
    658      *
    659      * @return the head of the queue represented by this deque
    660      * @throws NoSuchElementException if this deque is empty
    661      */
    662     public E element() {
    663         return getFirst();
    664     }
    665 
    666     public E peek() {
    667         return peekFirst();
    668     }
    669 
    670     /**
    671      * Returns the number of additional elements that this deque can ideally
    672      * (in the absence of memory or resource constraints) accept without
    673      * blocking. This is always equal to the initial capacity of this deque
    674      * less the current {@code size} of this deque.
    675      *
    676      * <p>Note that you <em>cannot</em> always tell if an attempt to insert
    677      * an element will succeed by inspecting {@code remainingCapacity}
    678      * because it may be the case that another thread is about to
    679      * insert or remove an element.
    680      */
    681     public int remainingCapacity() {
    682         final ReentrantLock lock = this.lock;
    683         lock.lock();
    684         try {
    685             return capacity - count;
    686         } finally {
    687             lock.unlock();
    688         }
    689     }
    690 
    691     /**
    692      * @throws UnsupportedOperationException {@inheritDoc}
    693      * @throws ClassCastException            {@inheritDoc}
    694      * @throws NullPointerException          {@inheritDoc}
    695      * @throws IllegalArgumentException      {@inheritDoc}
    696      */
    697     public int drainTo(Collection<? super E> c) {
    698         return drainTo(c, Integer.MAX_VALUE);
    699     }
    700 
    701     /**
    702      * @throws UnsupportedOperationException {@inheritDoc}
    703      * @throws ClassCastException            {@inheritDoc}
    704      * @throws NullPointerException          {@inheritDoc}
    705      * @throws IllegalArgumentException      {@inheritDoc}
    706      */
    707     public int drainTo(Collection<? super E> c, int maxElements) {
    708         if (c == null)
    709             throw new NullPointerException();
    710         if (c == this)
    711             throw new IllegalArgumentException();
    712         final ReentrantLock lock = this.lock;
    713         lock.lock();
    714         try {
    715             int n = Math.min(maxElements, count);
    716             for (int i = 0; i < n; i++) {
    717                 c.add(first.item);   // In this order, in case add() throws.
    718                 unlinkFirst();
    719             }
    720             return n;
    721         } finally {
    722             lock.unlock();
    723         }
    724     }
    725 
    726     // Stack methods
    727 
    728     /**
    729      * @throws IllegalStateException {@inheritDoc}
    730      * @throws NullPointerException  {@inheritDoc}
    731      */
    732     public void push(E e) {
    733         addFirst(e);
    734     }
    735 
    736     /**
    737      * @throws NoSuchElementException {@inheritDoc}
    738      */
    739     public E pop() {
    740         return removeFirst();
    741     }
    742 
    743     // Collection methods
    744 
    745     /**
    746      * Removes the first occurrence of the specified element from this deque.
    747      * If the deque does not contain the element, it is unchanged.
    748      * More formally, removes the first element {@code e} such that
    749      * {@code o.equals(e)} (if such an element exists).
    750      * Returns {@code true} if this deque contained the specified element
    751      * (or equivalently, if this deque changed as a result of the call).
    752      *
    753      * <p>This method is equivalent to
    754      * {@link #removeFirstOccurrence(Object) removeFirstOccurrence}.
    755      *
    756      * @param o element to be removed from this deque, if present
    757      * @return {@code true} if this deque changed as a result of the call
    758      */
    759     public boolean remove(Object o) {
    760         return removeFirstOccurrence(o);
    761     }
    762 
    763     /**
    764      * Returns the number of elements in this deque.
    765      *
    766      * @return the number of elements in this deque
    767      */
    768     public int size() {
    769         final ReentrantLock lock = this.lock;
    770         lock.lock();
    771         try {
    772             return count;
    773         } finally {
    774             lock.unlock();
    775         }
    776     }
    777 
    778     /**
    779      * Returns {@code true} if this deque contains the specified element.
    780      * More formally, returns {@code true} if and only if this deque contains
    781      * at least one element {@code e} such that {@code o.equals(e)}.
    782      *
    783      * @param o object to be checked for containment in this deque
    784      * @return {@code true} if this deque contains the specified element
    785      */
    786     public boolean contains(Object o) {
    787         if (o == null) return false;
    788         final ReentrantLock lock = this.lock;
    789         lock.lock();
    790         try {
    791             for (Node<E> p = first; p != null; p = p.next)
    792                 if (o.equals(p.item))
    793                     return true;
    794             return false;
    795         } finally {
    796             lock.unlock();
    797         }
    798     }
    799 
    800     /*
    801      * TODO: Add support for more efficient bulk operations.
    802      *
    803      * We don't want to acquire the lock for every iteration, but we
    804      * also want other threads a chance to interact with the
    805      * collection, especially when count is close to capacity.
    806      */
    807 
    808 //     /**
    809 //      * Adds all of the elements in the specified collection to this
    810 //      * queue.  Attempts to addAll of a queue to itself result in
    811 //      * {@code IllegalArgumentException}. Further, the behavior of
    812 //      * this operation is undefined if the specified collection is
    813 //      * modified while the operation is in progress.
    814 //      *
    815 //      * @param c collection containing elements to be added to this queue
    816 //      * @return {@code true} if this queue changed as a result of the call
    817 //      * @throws ClassCastException            {@inheritDoc}
    818 //      * @throws NullPointerException          {@inheritDoc}
    819 //      * @throws IllegalArgumentException      {@inheritDoc}
    820 //      * @throws IllegalStateException         {@inheritDoc}
    821 //      * @see #add(Object)
    822 //      */
    823 //     public boolean addAll(Collection<? extends E> c) {
    824 //         if (c == null)
    825 //             throw new NullPointerException();
    826 //         if (c == this)
    827 //             throw new IllegalArgumentException();
    828 //         final ReentrantLock lock = this.lock;
    829 //         lock.lock();
    830 //         try {
    831 //             boolean modified = false;
    832 //             for (E e : c)
    833 //                 if (linkLast(e))
    834 //                     modified = true;
    835 //             return modified;
    836 //         } finally {
    837 //             lock.unlock();
    838 //         }
    839 //     }
    840 
    841     /**
    842      * Returns an array containing all of the elements in this deque, in
    843      * proper sequence (from first to last element).
    844      *
    845      * <p>The returned array will be "safe" in that no references to it are
    846      * maintained by this deque.  (In other words, this method must allocate
    847      * a new array).  The caller is thus free to modify the returned array.
    848      *
    849      * <p>This method acts as bridge between array-based and collection-based
    850      * APIs.
    851      *
    852      * @return an array containing all of the elements in this deque
    853      */
    854     @SuppressWarnings("unchecked")
    855     public Object[] toArray() {
    856         final ReentrantLock lock = this.lock;
    857         lock.lock();
    858         try {
    859             Object[] a = new Object[count];
    860             int k = 0;
    861             for (Node<E> p = first; p != null; p = p.next)
    862                 a[k++] = p.item;
    863             return a;
    864         } finally {
    865             lock.unlock();
    866         }
    867     }
    868 
    869     /**
    870      * Returns an array containing all of the elements in this deque, in
    871      * proper sequence; the runtime type of the returned array is that of
    872      * the specified array.  If the deque fits in the specified array, it
    873      * is returned therein.  Otherwise, a new array is allocated with the
    874      * runtime type of the specified array and the size of this deque.
    875      *
    876      * <p>If this deque fits in the specified array with room to spare
    877      * (i.e., the array has more elements than this deque), the element in
    878      * the array immediately following the end of the deque is set to
    879      * {@code null}.
    880      *
    881      * <p>Like the {@link #toArray()} method, this method acts as bridge between
    882      * array-based and collection-based APIs.  Further, this method allows
    883      * precise control over the runtime type of the output array, and may,
    884      * under certain circumstances, be used to save allocation costs.
    885      *
    886      * <p>Suppose {@code x} is a deque known to contain only strings.
    887      * The following code can be used to dump the deque into a newly
    888      * allocated array of {@code String}:
    889      *
    890      * <pre>
    891      *     String[] y = x.toArray(new String[0]);</pre>
    892      *
    893      * Note that {@code toArray(new Object[0])} is identical in function to
    894      * {@code toArray()}.
    895      *
    896      * @param a the array into which the elements of the deque are to
    897      *          be stored, if it is big enough; otherwise, a new array of the
    898      *          same runtime type is allocated for this purpose
    899      * @return an array containing all of the elements in this deque
    900      * @throws ArrayStoreException if the runtime type of the specified array
    901      *         is not a supertype of the runtime type of every element in
    902      *         this deque
    903      * @throws NullPointerException if the specified array is null
    904      */
    905     @SuppressWarnings("unchecked")
    906     public <T> T[] toArray(T[] a) {
    907         final ReentrantLock lock = this.lock;
    908         lock.lock();
    909         try {
    910             if (a.length < count)
    911                 a = (T[])java.lang.reflect.Array.newInstance
    912                     (a.getClass().getComponentType(), count);
    913 
    914             int k = 0;
    915             for (Node<E> p = first; p != null; p = p.next)
    916                 a[k++] = (T)p.item;
    917             if (a.length > k)
    918                 a[k] = null;
    919             return a;
    920         } finally {
    921             lock.unlock();
    922         }
    923     }
    924 
    925     public String toString() {
    926         final ReentrantLock lock = this.lock;
    927         lock.lock();
    928         try {
    929             return super.toString();
    930         } finally {
    931             lock.unlock();
    932         }
    933     }
    934 
    935     /**
    936      * Atomically removes all of the elements from this deque.
    937      * The deque will be empty after this call returns.
    938      */
    939     public void clear() {
    940         final ReentrantLock lock = this.lock;
    941         lock.lock();
    942         try {
    943             for (Node<E> f = first; f != null; ) {
    944                 f.item = null;
    945                 Node<E> n = f.next;
    946                 f.prev = null;
    947                 f.next = null;
    948                 f = n;
    949             }
    950             first = last = null;
    951             count = 0;
    952             notFull.signalAll();
    953         } finally {
    954             lock.unlock();
    955         }
    956     }
    957 
    958     /**
    959      * Returns an iterator over the elements in this deque in proper sequence.
    960      * The elements will be returned in order from first (head) to last (tail).
    961      * The returned {@code Iterator} is a "weakly consistent" iterator that
    962      * will never throw {@link java.util.ConcurrentModificationException
    963      * ConcurrentModificationException},
    964      * and guarantees to traverse elements as they existed upon
    965      * construction of the iterator, and may (but is not guaranteed to)
    966      * reflect any modifications subsequent to construction.
    967      *
    968      * @return an iterator over the elements in this deque in proper sequence
    969      */
    970     public Iterator<E> iterator() {
    971         return new Itr();
    972     }
    973 
    974     /**
    975      * Returns an iterator over the elements in this deque in reverse
    976      * sequential order.  The elements will be returned in order from
    977      * last (tail) to first (head).
    978      * The returned {@code Iterator} is a "weakly consistent" iterator that
    979      * will never throw {@link java.util.ConcurrentModificationException
    980      * ConcurrentModificationException},
    981      * and guarantees to traverse elements as they existed upon
    982      * construction of the iterator, and may (but is not guaranteed to)
    983      * reflect any modifications subsequent to construction.
    984      */
    985     public Iterator<E> descendingIterator() {
    986         return new DescendingItr();
    987     }
    988 
    989     /**
    990      * Base class for Iterators for LinkedBlockingDeque
    991      */
    992     private abstract class AbstractItr implements Iterator<E> {
    993         /**
    994          * The next node to return in next()
    995          */
    996          Node<E> next;
    997 
    998         /**
    999          * nextItem holds on to item fields because once we claim that
   1000          * an element exists in hasNext(), we must return item read
   1001          * under lock (in advance()) even if it was in the process of
   1002          * being removed when hasNext() was called.
   1003          */
   1004         E nextItem;
   1005 
   1006         /**
   1007          * Node returned by most recent call to next. Needed by remove.
   1008          * Reset to null if this element is deleted by a call to remove.
   1009          */
   1010         private Node<E> lastRet;
   1011 
   1012         abstract Node<E> firstNode();
   1013         abstract Node<E> nextNode(Node<E> n);
   1014 
   1015         AbstractItr() {
   1016             // set to initial position
   1017             final ReentrantLock lock = LinkedBlockingDeque.this.lock;
   1018             lock.lock();
   1019             try {
   1020                 next = firstNode();
   1021                 nextItem = (next == null) ? null : next.item;
   1022             } finally {
   1023                 lock.unlock();
   1024             }
   1025         }
   1026 
   1027         /**
   1028          * Advances next.
   1029          */
   1030         void advance() {
   1031             final ReentrantLock lock = LinkedBlockingDeque.this.lock;
   1032             lock.lock();
   1033             try {
   1034                 // assert next != null;
   1035                 Node<E> s = nextNode(next);
   1036                 if (s == next) {
   1037                     next = firstNode();
   1038                 } else {
   1039                     // Skip over removed nodes.
   1040                     // May be necessary if multiple interior Nodes are removed.
   1041                     while (s != null && s.item == null)
   1042                         s = nextNode(s);
   1043                     next = s;
   1044                 }
   1045                 nextItem = (next == null) ? null : next.item;
   1046             } finally {
   1047                 lock.unlock();
   1048             }
   1049         }
   1050 
   1051         public boolean hasNext() {
   1052             return next != null;
   1053         }
   1054 
   1055         public E next() {
   1056             if (next == null)
   1057                 throw new NoSuchElementException();
   1058             lastRet = next;
   1059             E x = nextItem;
   1060             advance();
   1061             return x;
   1062         }
   1063 
   1064         public void remove() {
   1065             Node<E> n = lastRet;
   1066             if (n == null)
   1067                 throw new IllegalStateException();
   1068             lastRet = null;
   1069             final ReentrantLock lock = LinkedBlockingDeque.this.lock;
   1070             lock.lock();
   1071             try {
   1072                 if (n.item != null)
   1073                     unlink(n);
   1074             } finally {
   1075                 lock.unlock();
   1076             }
   1077         }
   1078     }
   1079 
   1080     /** Forward iterator */
   1081     private class Itr extends AbstractItr {
   1082         Node<E> firstNode() { return first; }
   1083         Node<E> nextNode(Node<E> n) { return n.next; }
   1084     }
   1085 
   1086     /** Descending iterator */
   1087     private class DescendingItr extends AbstractItr {
   1088         Node<E> firstNode() { return last; }
   1089         Node<E> nextNode(Node<E> n) { return n.prev; }
   1090     }
   1091 
   1092     /**
   1093      * Save the state of this deque to a stream (that is, serialize it).
   1094      *
   1095      * @serialData The capacity (int), followed by elements (each an
   1096      * {@code Object}) in the proper order, followed by a null
   1097      * @param s the stream
   1098      */
   1099     private void writeObject(java.io.ObjectOutputStream s)
   1100         throws java.io.IOException {
   1101         final ReentrantLock lock = this.lock;
   1102         lock.lock();
   1103         try {
   1104             // Write out capacity and any hidden stuff
   1105             s.defaultWriteObject();
   1106             // Write out all elements in the proper order.
   1107             for (Node<E> p = first; p != null; p = p.next)
   1108                 s.writeObject(p.item);
   1109             // Use trailing null as sentinel
   1110             s.writeObject(null);
   1111         } finally {
   1112             lock.unlock();
   1113         }
   1114     }
   1115 
   1116     /**
   1117      * Reconstitute this deque from a stream (that is,
   1118      * deserialize it).
   1119      * @param s the stream
   1120      */
   1121     private void readObject(java.io.ObjectInputStream s)
   1122         throws java.io.IOException, ClassNotFoundException {
   1123         s.defaultReadObject();
   1124         count = 0;
   1125         first = null;
   1126         last = null;
   1127         // Read in all elements and place in queue
   1128         for (;;) {
   1129             @SuppressWarnings("unchecked")
   1130             E item = (E)s.readObject();
   1131             if (item == null)
   1132                 break;
   1133             add(item);
   1134         }
   1135     }
   1136 
   1137 }
   1138