ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jdk8/java/util/concurrent/LinkedBlockingDeque.java
Revision: 1.3
Committed: Sat Dec 17 21:56:54 2016 UTC (7 years, 4 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +193 -106 lines
Log Message:
sync with src/main

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