ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/LinkedBlockingDeque.java
Revision: 1.20
Committed: Sun Feb 15 23:41:38 2009 UTC (15 years, 3 months ago) by dl
Branch: MAIN
Changes since 1.19: +2 -0 lines
Log Message:
Null fields on unlink to help GC

File Contents

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