ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/LinkedBlockingDeque.java
Revision: 1.22
Committed: Wed Jul 29 20:53:30 2009 UTC (14 years, 10 months ago) by jsr166
Branch: MAIN
Changes since 1.21: +4 -2 lines
Log Message:
6866554: Misc. javadoc warnings

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 jsr166 1.21
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 dl 1.1
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 jsr166 1.9 * contains}, {@link #iterator iterator.remove()}, and the bulk
31 dl 1.1 * 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 jsr166 1.9 * Iterator} interfaces.
36     *
37     * <p>This class is a member of the
38 jsr166 1.18 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
39 jsr166 1.9 * Java Collections Framework</a>.
40 dl 1.1 *
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 jsr166 1.21 *
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 dl 1.1 */
67    
68 jsr166 1.9 /*
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 dl 1.1 private static final long serialVersionUID = -387911632671998426L;
76    
77     /** Doubly-linked list node class */
78     static final class Node<E> {
79 jsr166 1.21 /**
80     * The item, or null if this node has been removed.
81     */
82 jsr166 1.19 E item;
83 jsr166 1.21
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 dl 1.1 Node<E> prev;
91 jsr166 1.21
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 dl 1.1 Node<E> next;
99 jsr166 1.21
100 dl 1.1 Node(E x, Node<E> p, Node<E> n) {
101     item = x;
102     prev = p;
103     next = n;
104     }
105     }
106    
107 jsr166 1.21 /**
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 dl 1.1 /** Number of items in the deque */
122     private transient int count;
123 jsr166 1.21
124 dl 1.1 /** Maximum number of items in the deque */
125     private final int capacity;
126 jsr166 1.21
127 dl 1.1 /** Main lock guarding all access */
128 jsr166 1.21 final ReentrantLock lock = new ReentrantLock();
129    
130 dl 1.1 /** Condition for waiting takes */
131     private final Condition notEmpty = lock.newCondition();
132 jsr166 1.21
133 dl 1.1 /** Condition for waiting puts */
134     private final Condition notFull = lock.newCondition();
135    
136     /**
137 jsr166 1.21 * Creates a {@code LinkedBlockingDeque} with a capacity of
138 dl 1.1 * {@link Integer#MAX_VALUE}.
139     */
140     public LinkedBlockingDeque() {
141     this(Integer.MAX_VALUE);
142     }
143    
144     /**
145 jsr166 1.21 * Creates a {@code LinkedBlockingDeque} with the given (fixed) capacity.
146 jsr166 1.9 *
147 dl 1.1 * @param capacity the capacity of this deque
148 jsr166 1.21 * @throws IllegalArgumentException if {@code capacity} is less than 1
149 dl 1.1 */
150     public LinkedBlockingDeque(int capacity) {
151     if (capacity <= 0) throw new IllegalArgumentException();
152     this.capacity = capacity;
153     }
154    
155     /**
156 jsr166 1.21 * Creates a {@code LinkedBlockingDeque} with a capacity of
157 jsr166 1.9 * {@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 dl 1.1 * @param c the collection of elements to initially contain
162 jsr166 1.9 * @throws NullPointerException if the specified collection or any
163     * of its elements are null
164 dl 1.1 */
165     public LinkedBlockingDeque(Collection<? extends E> c) {
166     this(Integer.MAX_VALUE);
167 jsr166 1.21 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 dl 1.1 }
180    
181    
182     // Basic linking and unlinking operations, called only while holding lock
183    
184     /**
185 jsr166 1.3 * Links e as first element, or returns false if full.
186 dl 1.1 */
187     private boolean linkFirst(E e) {
188 jsr166 1.21 // assert lock.isHeldByCurrentThread();
189 dl 1.1 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 jsr166 1.21 ++count;
199 dl 1.1 notEmpty.signal();
200     return true;
201     }
202    
203     /**
204 jsr166 1.3 * Links e as last element, or returns false if full.
205 dl 1.1 */
206     private boolean linkLast(E e) {
207 jsr166 1.21 // assert lock.isHeldByCurrentThread();
208 dl 1.1 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 jsr166 1.21 ++count;
218 dl 1.1 notEmpty.signal();
219     return true;
220     }
221    
222     /**
223 jsr166 1.3 * Removes and returns first element, or null if empty.
224 dl 1.1 */
225     private E unlinkFirst() {
226 jsr166 1.21 // assert lock.isHeldByCurrentThread();
227 dl 1.1 Node<E> f = first;
228     if (f == null)
229     return null;
230     Node<E> n = f.next;
231 jsr166 1.21 E item = f.item;
232     f.item = null;
233     f.next = f; // help GC
234 dl 1.1 first = n;
235 jsr166 1.3 if (n == null)
236 dl 1.1 last = null;
237 jsr166 1.3 else
238 dl 1.1 n.prev = null;
239     --count;
240     notFull.signal();
241 jsr166 1.21 return item;
242 dl 1.1 }
243    
244     /**
245 jsr166 1.3 * Removes and returns last element, or null if empty.
246 dl 1.1 */
247     private E unlinkLast() {
248 jsr166 1.21 // assert lock.isHeldByCurrentThread();
249 dl 1.1 Node<E> l = last;
250     if (l == null)
251     return null;
252     Node<E> p = l.prev;
253 jsr166 1.21 E item = l.item;
254     l.item = null;
255     l.prev = l; // help GC
256 dl 1.1 last = p;
257 jsr166 1.3 if (p == null)
258 dl 1.1 first = null;
259 jsr166 1.3 else
260 dl 1.1 p.next = null;
261     --count;
262     notFull.signal();
263 jsr166 1.21 return item;
264 dl 1.1 }
265    
266     /**
267 jsr166 1.21 * Unlinks x.
268 dl 1.1 */
269 jsr166 1.21 void unlink(Node<E> x) {
270     // assert lock.isHeldByCurrentThread();
271 dl 1.1 Node<E> p = x.prev;
272     Node<E> n = x.next;
273     if (p == null) {
274 jsr166 1.21 unlinkFirst();
275 dl 1.1 } else if (n == null) {
276 jsr166 1.21 unlinkLast();
277 dl 1.1 } else {
278     p.next = n;
279     n.prev = p;
280 jsr166 1.21 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 dl 1.1 }
286     }
287    
288 jsr166 1.9 // BlockingDeque methods
289 dl 1.1
290 jsr166 1.9 /**
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 jsr166 1.6 public boolean offerFirst(E e) {
312     if (e == null) throw new NullPointerException();
313 jsr166 1.21 final ReentrantLock lock = this.lock;
314 dl 1.1 lock.lock();
315     try {
316 jsr166 1.6 return linkFirst(e);
317 dl 1.1 } finally {
318     lock.unlock();
319     }
320     }
321    
322 jsr166 1.9 /**
323     * @throws NullPointerException {@inheritDoc}
324     */
325 jsr166 1.6 public boolean offerLast(E e) {
326     if (e == null) throw new NullPointerException();
327 jsr166 1.21 final ReentrantLock lock = this.lock;
328 dl 1.1 lock.lock();
329     try {
330 jsr166 1.6 return linkLast(e);
331 dl 1.1 } finally {
332     lock.unlock();
333     }
334     }
335    
336 jsr166 1.9 /**
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 jsr166 1.21 final ReentrantLock lock = this.lock;
343 dl 1.1 lock.lock();
344     try {
345 jsr166 1.9 while (!linkFirst(e))
346     notFull.await();
347 dl 1.1 } finally {
348     lock.unlock();
349     }
350     }
351    
352 jsr166 1.9 /**
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 jsr166 1.21 final ReentrantLock lock = this.lock;
359 dl 1.1 lock.lock();
360     try {
361 jsr166 1.9 while (!linkLast(e))
362     notFull.await();
363 dl 1.1 } finally {
364     lock.unlock();
365     }
366     }
367    
368 jsr166 1.9 /**
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 jsr166 1.19 long nanos = unit.toNanos(timeout);
376 jsr166 1.21 final ReentrantLock lock = this.lock;
377 jsr166 1.9 lock.lockInterruptibly();
378 dl 1.1 try {
379 jsr166 1.21 while (!linkFirst(e)) {
380 jsr166 1.9 if (nanos <= 0)
381     return false;
382     nanos = notFull.awaitNanos(nanos);
383     }
384 jsr166 1.21 return true;
385 dl 1.1 } finally {
386     lock.unlock();
387     }
388     }
389    
390 jsr166 1.9 /**
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 jsr166 1.19 long nanos = unit.toNanos(timeout);
398 jsr166 1.21 final ReentrantLock lock = this.lock;
399 jsr166 1.9 lock.lockInterruptibly();
400 dl 1.1 try {
401 jsr166 1.21 while (!linkLast(e)) {
402 jsr166 1.9 if (nanos <= 0)
403     return false;
404     nanos = notFull.awaitNanos(nanos);
405     }
406 jsr166 1.21 return true;
407 dl 1.1 } finally {
408     lock.unlock();
409     }
410     }
411    
412 jsr166 1.9 /**
413     * @throws NoSuchElementException {@inheritDoc}
414     */
415     public E removeFirst() {
416     E x = pollFirst();
417 dl 1.1 if (x == null) throw new NoSuchElementException();
418     return x;
419     }
420    
421 jsr166 1.9 /**
422     * @throws NoSuchElementException {@inheritDoc}
423     */
424     public E removeLast() {
425     E x = pollLast();
426 dl 1.1 if (x == null) throw new NoSuchElementException();
427     return x;
428     }
429    
430 jsr166 1.9 public E pollFirst() {
431 jsr166 1.21 final ReentrantLock lock = this.lock;
432 dl 1.1 lock.lock();
433     try {
434 jsr166 1.9 return unlinkFirst();
435 dl 1.1 } finally {
436     lock.unlock();
437     }
438     }
439    
440 jsr166 1.9 public E pollLast() {
441 jsr166 1.21 final ReentrantLock lock = this.lock;
442 dl 1.1 lock.lock();
443     try {
444 jsr166 1.9 return unlinkLast();
445 dl 1.1 } finally {
446     lock.unlock();
447     }
448     }
449    
450     public E takeFirst() throws InterruptedException {
451 jsr166 1.21 final ReentrantLock lock = this.lock;
452 dl 1.1 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 jsr166 1.21 final ReentrantLock lock = this.lock;
465 dl 1.1 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 jsr166 1.9 public E pollFirst(long timeout, TimeUnit unit)
477 dl 1.1 throws InterruptedException {
478 jsr166 1.19 long nanos = unit.toNanos(timeout);
479 jsr166 1.21 final ReentrantLock lock = this.lock;
480 dl 1.1 lock.lockInterruptibly();
481     try {
482 jsr166 1.21 E x;
483     while ( (x = unlinkFirst()) == null) {
484 dl 1.1 if (nanos <= 0)
485 jsr166 1.9 return null;
486     nanos = notEmpty.awaitNanos(nanos);
487 dl 1.1 }
488 jsr166 1.21 return x;
489 dl 1.1 } finally {
490     lock.unlock();
491     }
492     }
493 jsr166 1.3
494 jsr166 1.9 public E pollLast(long timeout, TimeUnit unit)
495 dl 1.1 throws InterruptedException {
496 jsr166 1.19 long nanos = unit.toNanos(timeout);
497 jsr166 1.21 final ReentrantLock lock = this.lock;
498 dl 1.1 lock.lockInterruptibly();
499     try {
500 jsr166 1.21 E x;
501     while ( (x = unlinkLast()) == null) {
502 dl 1.1 if (nanos <= 0)
503 jsr166 1.9 return null;
504     nanos = notEmpty.awaitNanos(nanos);
505 dl 1.1 }
506 jsr166 1.21 return x;
507 dl 1.1 } finally {
508     lock.unlock();
509     }
510     }
511    
512 jsr166 1.9 /**
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 jsr166 1.21 final ReentrantLock lock = this.lock;
532 jsr166 1.9 lock.lock();
533     try {
534     return (first == null) ? null : first.item;
535     } finally {
536     lock.unlock();
537     }
538     }
539    
540     public E peekLast() {
541 jsr166 1.21 final ReentrantLock lock = this.lock;
542 jsr166 1.9 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 jsr166 1.21 final ReentrantLock lock = this.lock;
553 jsr166 1.9 lock.lock();
554 dl 1.1 try {
555 jsr166 1.9 for (Node<E> p = first; p != null; p = p.next) {
556     if (o.equals(p.item)) {
557     unlink(p);
558     return true;
559     }
560 dl 1.1 }
561 jsr166 1.9 return false;
562 dl 1.1 } finally {
563     lock.unlock();
564     }
565     }
566    
567 jsr166 1.9 public boolean removeLastOccurrence(Object o) {
568     if (o == null) return false;
569 jsr166 1.21 final ReentrantLock lock = this.lock;
570 jsr166 1.9 lock.lock();
571 dl 1.1 try {
572 jsr166 1.9 for (Node<E> p = last; p != null; p = p.prev) {
573     if (o.equals(p.item)) {
574     unlink(p);
575     return true;
576     }
577 dl 1.1 }
578 jsr166 1.9 return false;
579 dl 1.1 } finally {
580     lock.unlock();
581     }
582     }
583    
584 jsr166 1.9 // BlockingQueue methods
585 dl 1.1
586 jsr166 1.9 /**
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(Object) offer}.
590     *
591 jsr166 1.13 * <p>This method is equivalent to {@link #addLast}.
592 jsr166 1.9 *
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 jsr166 1.19 addLast(e);
599     return true;
600 jsr166 1.9 }
601    
602     /**
603     * @throws NullPointerException if the specified element is null
604     */
605     public boolean offer(E e) {
606 jsr166 1.19 return offerLast(e);
607 jsr166 1.9 }
608 dl 1.1
609 jsr166 1.9 /**
610     * @throws NullPointerException {@inheritDoc}
611     * @throws InterruptedException {@inheritDoc}
612     */
613     public void put(E e) throws InterruptedException {
614 jsr166 1.19 putLast(e);
615 jsr166 1.9 }
616 dl 1.1
617 jsr166 1.9 /**
618     * @throws NullPointerException {@inheritDoc}
619     * @throws InterruptedException {@inheritDoc}
620     */
621 jsr166 1.7 public boolean offer(E e, long timeout, TimeUnit unit)
622 jsr166 1.9 throws InterruptedException {
623 jsr166 1.19 return offerLast(e, timeout, unit);
624 jsr166 1.9 }
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 jsr166 1.19 return removeFirst();
638 jsr166 1.9 }
639    
640     public E poll() {
641 jsr166 1.19 return pollFirst();
642 jsr166 1.9 }
643    
644     public E take() throws InterruptedException {
645 jsr166 1.19 return takeFirst();
646 jsr166 1.9 }
647    
648     public E poll(long timeout, TimeUnit unit) throws InterruptedException {
649 jsr166 1.19 return pollFirst(timeout, unit);
650 jsr166 1.9 }
651 dl 1.1
652     /**
653 jsr166 1.9 * 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 dl 1.1 *
659 jsr166 1.9 * @return the head of the queue represented by this deque
660     * @throws NoSuchElementException if this deque is empty
661 dl 1.1 */
662 jsr166 1.9 public E element() {
663 jsr166 1.19 return getFirst();
664 jsr166 1.9 }
665    
666     public E peek() {
667 jsr166 1.19 return peekFirst();
668 dl 1.1 }
669    
670     /**
671 jsr166 1.4 * Returns the number of additional elements that this deque can ideally
672     * (in the absence of memory or resource constraints) accept without
673 dl 1.1 * blocking. This is always equal to the initial capacity of this deque
674 jsr166 1.21 * less the current {@code size} of this deque.
675 jsr166 1.4 *
676     * <p>Note that you <em>cannot</em> always tell if an attempt to insert
677 jsr166 1.21 * an element will succeed by inspecting {@code remainingCapacity}
678 jsr166 1.4 * because it may be the case that another thread is about to
679 jsr166 1.9 * insert or remove an element.
680 dl 1.1 */
681     public int remainingCapacity() {
682 jsr166 1.21 final ReentrantLock lock = this.lock;
683 dl 1.1 lock.lock();
684     try {
685     return capacity - count;
686     } finally {
687     lock.unlock();
688     }
689     }
690    
691 jsr166 1.9 /**
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 jsr166 1.21 return drainTo(c, Integer.MAX_VALUE);
699 dl 1.1 }
700    
701 jsr166 1.9 /**
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 jsr166 1.21 final ReentrantLock lock = this.lock;
713 dl 1.1 lock.lock();
714     try {
715 jsr166 1.21 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 dl 1.1 }
720 jsr166 1.9 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 jsr166 1.19 addFirst(e);
734 jsr166 1.9 }
735    
736     /**
737     * @throws NoSuchElementException {@inheritDoc}
738     */
739     public E pop() {
740 jsr166 1.19 return removeFirst();
741 jsr166 1.9 }
742    
743     // Collection methods
744    
745 jsr166 1.11 /**
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 jsr166 1.21 * 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 jsr166 1.11 * (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 jsr166 1.21 * @return {@code true} if this deque changed as a result of the call
758 jsr166 1.11 */
759 jsr166 1.9 public boolean remove(Object o) {
760 jsr166 1.19 return removeFirstOccurrence(o);
761 jsr166 1.9 }
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 jsr166 1.21 final ReentrantLock lock = this.lock;
770 jsr166 1.9 lock.lock();
771     try {
772     return count;
773 dl 1.1 } finally {
774     lock.unlock();
775     }
776     }
777    
778 jsr166 1.9 /**
779 jsr166 1.21 * 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 jsr166 1.9 *
783     * @param o object to be checked for containment in this deque
784 jsr166 1.21 * @return {@code true} if this deque contains the specified element
785 jsr166 1.9 */
786     public boolean contains(Object o) {
787     if (o == null) return false;
788 jsr166 1.21 final ReentrantLock lock = this.lock;
789 dl 1.1 lock.lock();
790     try {
791 jsr166 1.9 for (Node<E> p = first; p != null; p = p.next)
792     if (o.equals(p.item))
793 dl 1.1 return true;
794     return false;
795     } finally {
796     lock.unlock();
797     }
798     }
799    
800 jsr166 1.21 /*
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 dl 1.1
841 jsr166 1.9 /**
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 jsr166 1.10 *
849 jsr166 1.9 * <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 jsr166 1.21 @SuppressWarnings("unchecked")
855 dl 1.1 public Object[] toArray() {
856 jsr166 1.21 final ReentrantLock lock = this.lock;
857 dl 1.1 lock.lock();
858     try {
859     Object[] a = new Object[count];
860     int k = 0;
861 jsr166 1.3 for (Node<E> p = first; p != null; p = p.next)
862 dl 1.1 a[k++] = p.item;
863     return a;
864     } finally {
865     lock.unlock();
866     }
867     }
868    
869 jsr166 1.9 /**
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 jsr166 1.21 * {@code null}.
880 jsr166 1.9 *
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 jsr166 1.21 * <p>Suppose {@code x} is a deque known to contain only strings.
887 jsr166 1.9 * The following code can be used to dump the deque into a newly
888 jsr166 1.21 * allocated array of {@code String}:
889 jsr166 1.9 *
890     * <pre>
891     * String[] y = x.toArray(new String[0]);</pre>
892     *
893 jsr166 1.21 * Note that {@code toArray(new Object[0])} is identical in function to
894     * {@code toArray()}.
895 jsr166 1.9 *
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 jsr166 1.21 @SuppressWarnings("unchecked")
906 dl 1.1 public <T> T[] toArray(T[] a) {
907 jsr166 1.21 final ReentrantLock lock = this.lock;
908 dl 1.1 lock.lock();
909     try {
910     if (a.length < count)
911 jsr166 1.21 a = (T[])java.lang.reflect.Array.newInstance
912     (a.getClass().getComponentType(), count);
913 dl 1.1
914     int k = 0;
915 jsr166 1.3 for (Node<E> p = first; p != null; p = p.next)
916 dl 1.1 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 jsr166 1.21 final ReentrantLock lock = this.lock;
927 dl 1.1 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 jsr166 1.21 final ReentrantLock lock = this.lock;
941 dl 1.1 lock.lock();
942     try {
943 jsr166 1.21 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 dl 1.1 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 jsr166 1.9 * The elements will be returned in order from first (head) to last (tail).
961 jsr166 1.21 * The returned {@code Iterator} is a "weakly consistent" iterator that
962 jsr166 1.22 * will never throw {@link java.util.ConcurrentModificationException
963     * ConcurrentModificationException},
964 dl 1.1 * 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 jsr166 1.9 * @return an iterator over the elements in this deque in proper sequence
969 dl 1.1 */
970     public Iterator<E> iterator() {
971     return new Itr();
972     }
973    
974     /**
975 dl 1.14 * 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 jsr166 1.21 * The returned {@code Iterator} is a "weakly consistent" iterator that
979 jsr166 1.22 * will never throw {@link java.util.ConcurrentModificationException
980     * ConcurrentModificationException},
981 dl 1.14 * 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 dl 1.1 */
992 dl 1.16 private abstract class AbstractItr implements Iterator<E> {
993 jsr166 1.15 /**
994 jsr166 1.21 * The next node to return in next()
995 dl 1.14 */
996     Node<E> next;
997 dl 1.1
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 jsr166 1.3 */
1004 dl 1.14 E nextItem;
1005 dl 1.1
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 dl 1.16 private Node<E> lastRet;
1011    
1012 jsr166 1.21 abstract Node<E> firstNode();
1013     abstract Node<E> nextNode(Node<E> n);
1014    
1015 dl 1.16 AbstractItr() {
1016 jsr166 1.21 // 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 dl 1.16 }
1026 dl 1.1
1027     /**
1028 jsr166 1.21 * Advances next.
1029 dl 1.1 */
1030 jsr166 1.21 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 dl 1.1
1051     public boolean hasNext() {
1052     return next != null;
1053     }
1054    
1055     public E next() {
1056     if (next == null)
1057     throw new NoSuchElementException();
1058 dl 1.14 lastRet = next;
1059 dl 1.1 E x = nextItem;
1060     advance();
1061     return x;
1062     }
1063    
1064     public void remove() {
1065 dl 1.14 Node<E> n = lastRet;
1066 dl 1.1 if (n == null)
1067     throw new IllegalStateException();
1068 dl 1.14 lastRet = null;
1069     final ReentrantLock lock = LinkedBlockingDeque.this.lock;
1070     lock.lock();
1071     try {
1072 jsr166 1.21 if (n.item != null)
1073     unlink(n);
1074 dl 1.14 } finally {
1075     lock.unlock();
1076     }
1077     }
1078     }
1079    
1080 jsr166 1.21 /** 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 dl 1.16 private class DescendingItr extends AbstractItr {
1088 jsr166 1.21 Node<E> firstNode() { return last; }
1089     Node<E> nextNode(Node<E> n) { return n.prev; }
1090 dl 1.14 }
1091    
1092 dl 1.1 /**
1093 jsr166 1.3 * Save the state of this deque to a stream (that is, serialize it).
1094 dl 1.1 *
1095     * @serialData The capacity (int), followed by elements (each an
1096 jsr166 1.21 * {@code Object}) in the proper order, followed by a null
1097 dl 1.1 * @param s the stream
1098     */
1099     private void writeObject(java.io.ObjectOutputStream s)
1100     throws java.io.IOException {
1101 jsr166 1.21 final ReentrantLock lock = this.lock;
1102 dl 1.1 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 jsr166 1.3 * Reconstitute this deque from a stream (that is,
1118 dl 1.1 * 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 jsr166 1.21 @SuppressWarnings("unchecked")
1130 dl 1.1 E item = (E)s.readObject();
1131     if (item == null)
1132     break;
1133     add(item);
1134     }
1135     }
1136 jsr166 1.3
1137 dl 1.1 }