ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/LinkedBlockingDeque.java
Revision: 1.46
Committed: Thu May 2 06:38:33 2013 UTC (11 years, 1 month ago) by jsr166
Branch: MAIN
Changes since 1.45: +7 -8 lines
Log Message:
fix up exception spec javadoc for deque methods

File Contents

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