ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/LinkedBlockingDeque.java
Revision: 1.76
Committed: Wed Dec 28 04:53:47 2016 UTC (7 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.75: +6 -2 lines
Log Message:
succ: bytecode golf

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 import java.util.function.Predicate;
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 deque
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 addAll(c);
171 }
172
173
174 // Basic linking and unlinking operations, called only while holding lock
175
176 /**
177 * Links node as first element, or returns false if full.
178 */
179 private boolean linkFirst(Node<E> node) {
180 // assert lock.isHeldByCurrentThread();
181 if (count >= capacity)
182 return false;
183 Node<E> f = first;
184 node.next = f;
185 first = node;
186 if (last == null)
187 last = node;
188 else
189 f.prev = node;
190 ++count;
191 notEmpty.signal();
192 return true;
193 }
194
195 /**
196 * Links node as last element, or returns false if full.
197 */
198 private boolean linkLast(Node<E> node) {
199 // assert lock.isHeldByCurrentThread();
200 if (count >= capacity)
201 return false;
202 Node<E> l = last;
203 node.prev = l;
204 last = node;
205 if (first == null)
206 first = node;
207 else
208 l.next = node;
209 ++count;
210 notEmpty.signal();
211 return true;
212 }
213
214 /**
215 * Removes and returns first element, or null if empty.
216 */
217 private E unlinkFirst() {
218 // assert lock.isHeldByCurrentThread();
219 Node<E> f = first;
220 if (f == null)
221 return null;
222 Node<E> n = f.next;
223 E item = f.item;
224 f.item = null;
225 f.next = f; // help GC
226 first = n;
227 if (n == null)
228 last = null;
229 else
230 n.prev = null;
231 --count;
232 notFull.signal();
233 return item;
234 }
235
236 /**
237 * Removes and returns last element, or null if empty.
238 */
239 private E unlinkLast() {
240 // assert lock.isHeldByCurrentThread();
241 Node<E> l = last;
242 if (l == null)
243 return null;
244 Node<E> p = l.prev;
245 E item = l.item;
246 l.item = null;
247 l.prev = l; // help GC
248 last = p;
249 if (p == null)
250 first = null;
251 else
252 p.next = null;
253 --count;
254 notFull.signal();
255 return item;
256 }
257
258 /**
259 * Unlinks x.
260 */
261 void unlink(Node<E> x) {
262 // assert lock.isHeldByCurrentThread();
263 // assert x.item != null;
264 Node<E> p = x.prev;
265 Node<E> n = x.next;
266 if (p == null) {
267 unlinkFirst();
268 } else if (n == null) {
269 unlinkLast();
270 } else {
271 p.next = n;
272 n.prev = p;
273 x.item = null;
274 // Don't mess with x's links. They may still be in use by
275 // an iterator.
276 --count;
277 notFull.signal();
278 }
279 }
280
281 // BlockingDeque methods
282
283 /**
284 * @throws IllegalStateException if this deque is full
285 * @throws NullPointerException {@inheritDoc}
286 */
287 public void addFirst(E e) {
288 if (!offerFirst(e))
289 throw new IllegalStateException("Deque full");
290 }
291
292 /**
293 * @throws IllegalStateException if this deque is full
294 * @throws NullPointerException {@inheritDoc}
295 */
296 public void addLast(E e) {
297 if (!offerLast(e))
298 throw new IllegalStateException("Deque full");
299 }
300
301 /**
302 * @throws NullPointerException {@inheritDoc}
303 */
304 public boolean offerFirst(E e) {
305 if (e == null) throw new NullPointerException();
306 Node<E> node = new Node<E>(e);
307 final ReentrantLock lock = this.lock;
308 lock.lock();
309 try {
310 return linkFirst(node);
311 } finally {
312 // checkInvariants();
313 lock.unlock();
314 }
315 }
316
317 /**
318 * @throws NullPointerException {@inheritDoc}
319 */
320 public boolean offerLast(E e) {
321 if (e == null) throw new NullPointerException();
322 Node<E> node = new Node<E>(e);
323 final ReentrantLock lock = this.lock;
324 lock.lock();
325 try {
326 return linkLast(node);
327 } finally {
328 // checkInvariants();
329 lock.unlock();
330 }
331 }
332
333 /**
334 * @throws NullPointerException {@inheritDoc}
335 * @throws InterruptedException {@inheritDoc}
336 */
337 public void putFirst(E e) throws InterruptedException {
338 if (e == null) throw new NullPointerException();
339 Node<E> node = new Node<E>(e);
340 final ReentrantLock lock = this.lock;
341 lock.lock();
342 try {
343 while (!linkFirst(node))
344 notFull.await();
345 } finally {
346 // checkInvariants();
347 lock.unlock();
348 }
349 }
350
351 /**
352 * @throws NullPointerException {@inheritDoc}
353 * @throws InterruptedException {@inheritDoc}
354 */
355 public void putLast(E e) throws InterruptedException {
356 if (e == null) throw new NullPointerException();
357 Node<E> node = new Node<E>(e);
358 final ReentrantLock lock = this.lock;
359 lock.lock();
360 try {
361 while (!linkLast(node))
362 notFull.await();
363 } finally {
364 // checkInvariants();
365 lock.unlock();
366 }
367 }
368
369 /**
370 * @throws NullPointerException {@inheritDoc}
371 * @throws InterruptedException {@inheritDoc}
372 */
373 public boolean offerFirst(E e, long timeout, TimeUnit unit)
374 throws InterruptedException {
375 if (e == null) throw new NullPointerException();
376 Node<E> node = new Node<E>(e);
377 long nanos = unit.toNanos(timeout);
378 final ReentrantLock lock = this.lock;
379 lock.lockInterruptibly();
380 try {
381 while (!linkFirst(node)) {
382 if (nanos <= 0L)
383 return false;
384 nanos = notFull.awaitNanos(nanos);
385 }
386 return true;
387 } finally {
388 // checkInvariants();
389 lock.unlock();
390 }
391 }
392
393 /**
394 * @throws NullPointerException {@inheritDoc}
395 * @throws InterruptedException {@inheritDoc}
396 */
397 public boolean offerLast(E e, long timeout, TimeUnit unit)
398 throws InterruptedException {
399 if (e == null) throw new NullPointerException();
400 Node<E> node = new Node<E>(e);
401 long nanos = unit.toNanos(timeout);
402 final ReentrantLock lock = this.lock;
403 lock.lockInterruptibly();
404 try {
405 while (!linkLast(node)) {
406 if (nanos <= 0L)
407 return false;
408 nanos = notFull.awaitNanos(nanos);
409 }
410 return true;
411 } finally {
412 // checkInvariants();
413 lock.unlock();
414 }
415 }
416
417 /**
418 * @throws NoSuchElementException {@inheritDoc}
419 */
420 public E removeFirst() {
421 E x = pollFirst();
422 if (x == null) throw new NoSuchElementException();
423 return x;
424 }
425
426 /**
427 * @throws NoSuchElementException {@inheritDoc}
428 */
429 public E removeLast() {
430 E x = pollLast();
431 if (x == null) throw new NoSuchElementException();
432 return x;
433 }
434
435 public E pollFirst() {
436 final ReentrantLock lock = this.lock;
437 lock.lock();
438 try {
439 return unlinkFirst();
440 } finally {
441 // checkInvariants();
442 lock.unlock();
443 }
444 }
445
446 public E pollLast() {
447 final ReentrantLock lock = this.lock;
448 lock.lock();
449 try {
450 return unlinkLast();
451 } finally {
452 // checkInvariants();
453 lock.unlock();
454 }
455 }
456
457 public E takeFirst() throws InterruptedException {
458 final ReentrantLock lock = this.lock;
459 lock.lock();
460 try {
461 E x;
462 while ( (x = unlinkFirst()) == null)
463 notEmpty.await();
464 return x;
465 } finally {
466 // checkInvariants();
467 lock.unlock();
468 }
469 }
470
471 public E takeLast() throws InterruptedException {
472 final ReentrantLock lock = this.lock;
473 lock.lock();
474 try {
475 E x;
476 while ( (x = unlinkLast()) == null)
477 notEmpty.await();
478 return x;
479 } finally {
480 // checkInvariants();
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 <= 0L)
494 return null;
495 nanos = notEmpty.awaitNanos(nanos);
496 }
497 return x;
498 } finally {
499 // checkInvariants();
500 lock.unlock();
501 }
502 }
503
504 public E pollLast(long timeout, TimeUnit unit)
505 throws InterruptedException {
506 long nanos = unit.toNanos(timeout);
507 final ReentrantLock lock = this.lock;
508 lock.lockInterruptibly();
509 try {
510 E x;
511 while ( (x = unlinkLast()) == null) {
512 if (nanos <= 0L)
513 return null;
514 nanos = notEmpty.awaitNanos(nanos);
515 }
516 return x;
517 } finally {
518 // checkInvariants();
519 lock.unlock();
520 }
521 }
522
523 /**
524 * @throws NoSuchElementException {@inheritDoc}
525 */
526 public E getFirst() {
527 E x = peekFirst();
528 if (x == null) throw new NoSuchElementException();
529 return x;
530 }
531
532 /**
533 * @throws NoSuchElementException {@inheritDoc}
534 */
535 public E getLast() {
536 E x = peekLast();
537 if (x == null) throw new NoSuchElementException();
538 return x;
539 }
540
541 public E peekFirst() {
542 final ReentrantLock lock = this.lock;
543 lock.lock();
544 try {
545 return (first == null) ? null : first.item;
546 } finally {
547 // checkInvariants();
548 lock.unlock();
549 }
550 }
551
552 public E peekLast() {
553 final ReentrantLock lock = this.lock;
554 lock.lock();
555 try {
556 return (last == null) ? null : last.item;
557 } finally {
558 // checkInvariants();
559 lock.unlock();
560 }
561 }
562
563 public boolean removeFirstOccurrence(Object o) {
564 if (o == null) return false;
565 final ReentrantLock lock = this.lock;
566 lock.lock();
567 try {
568 for (Node<E> p = first; p != null; p = p.next) {
569 if (o.equals(p.item)) {
570 unlink(p);
571 return true;
572 }
573 }
574 return false;
575 } finally {
576 // checkInvariants();
577 lock.unlock();
578 }
579 }
580
581 public boolean removeLastOccurrence(Object o) {
582 if (o == null) return false;
583 final ReentrantLock lock = this.lock;
584 lock.lock();
585 try {
586 for (Node<E> p = last; p != null; p = p.prev) {
587 if (o.equals(p.item)) {
588 unlink(p);
589 return true;
590 }
591 }
592 return false;
593 } finally {
594 // checkInvariants();
595 lock.unlock();
596 }
597 }
598
599 // BlockingQueue methods
600
601 /**
602 * Inserts the specified element at the end of this deque unless it would
603 * violate capacity restrictions. When using a capacity-restricted deque,
604 * it is generally preferable to use method {@link #offer(Object) offer}.
605 *
606 * <p>This method is equivalent to {@link #addLast}.
607 *
608 * @throws IllegalStateException if this deque is full
609 * @throws NullPointerException if the specified element is null
610 */
611 public boolean add(E e) {
612 addLast(e);
613 return true;
614 }
615
616 /**
617 * @throws NullPointerException if the specified element is null
618 */
619 public boolean offer(E e) {
620 return offerLast(e);
621 }
622
623 /**
624 * @throws NullPointerException {@inheritDoc}
625 * @throws InterruptedException {@inheritDoc}
626 */
627 public void put(E e) throws InterruptedException {
628 putLast(e);
629 }
630
631 /**
632 * @throws NullPointerException {@inheritDoc}
633 * @throws InterruptedException {@inheritDoc}
634 */
635 public boolean offer(E e, long timeout, TimeUnit unit)
636 throws InterruptedException {
637 return offerLast(e, timeout, unit);
638 }
639
640 /**
641 * Retrieves and removes the head of the queue represented by this deque.
642 * This method differs from {@link #poll poll} only in that it throws an
643 * exception if this deque is empty.
644 *
645 * <p>This method is equivalent to {@link #removeFirst() removeFirst}.
646 *
647 * @return the head of the queue represented by this deque
648 * @throws NoSuchElementException if this deque is empty
649 */
650 public E remove() {
651 return removeFirst();
652 }
653
654 public E poll() {
655 return pollFirst();
656 }
657
658 public E take() throws InterruptedException {
659 return takeFirst();
660 }
661
662 public E poll(long timeout, TimeUnit unit) throws InterruptedException {
663 return pollFirst(timeout, unit);
664 }
665
666 /**
667 * Retrieves, but does not remove, the head of the queue represented by
668 * this deque. This method differs from {@link #peek peek} only in that
669 * it throws an exception if this deque is empty.
670 *
671 * <p>This method is equivalent to {@link #getFirst() getFirst}.
672 *
673 * @return the head of the queue represented by this deque
674 * @throws NoSuchElementException if this deque is empty
675 */
676 public E element() {
677 return getFirst();
678 }
679
680 public E peek() {
681 return peekFirst();
682 }
683
684 /**
685 * Returns the number of additional elements that this deque can ideally
686 * (in the absence of memory or resource constraints) accept without
687 * blocking. This is always equal to the initial capacity of this deque
688 * less the current {@code size} of this deque.
689 *
690 * <p>Note that you <em>cannot</em> always tell if an attempt to insert
691 * an element will succeed by inspecting {@code remainingCapacity}
692 * because it may be the case that another thread is about to
693 * insert or remove an element.
694 */
695 public int remainingCapacity() {
696 final ReentrantLock lock = this.lock;
697 lock.lock();
698 try {
699 return capacity - count;
700 } finally {
701 // checkInvariants();
702 lock.unlock();
703 }
704 }
705
706 /**
707 * @throws UnsupportedOperationException {@inheritDoc}
708 * @throws ClassCastException {@inheritDoc}
709 * @throws NullPointerException {@inheritDoc}
710 * @throws IllegalArgumentException {@inheritDoc}
711 */
712 public int drainTo(Collection<? super E> c) {
713 return drainTo(c, Integer.MAX_VALUE);
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, int maxElements) {
723 Objects.requireNonNull(c);
724 if (c == this)
725 throw new IllegalArgumentException();
726 if (maxElements <= 0)
727 return 0;
728 final ReentrantLock lock = this.lock;
729 lock.lock();
730 try {
731 int n = Math.min(maxElements, count);
732 for (int i = 0; i < n; i++) {
733 c.add(first.item); // In this order, in case add() throws.
734 unlinkFirst();
735 }
736 return n;
737 } finally {
738 // checkInvariants();
739 lock.unlock();
740 }
741 }
742
743 // Stack methods
744
745 /**
746 * @throws IllegalStateException if this deque is full
747 * @throws NullPointerException {@inheritDoc}
748 */
749 public void push(E e) {
750 addFirst(e);
751 }
752
753 /**
754 * @throws NoSuchElementException {@inheritDoc}
755 */
756 public E pop() {
757 return removeFirst();
758 }
759
760 // Collection methods
761
762 /**
763 * Removes the first occurrence of the specified element from this deque.
764 * If the deque does not contain the element, it is unchanged.
765 * More formally, removes the first element {@code e} such that
766 * {@code o.equals(e)} (if such an element exists).
767 * Returns {@code true} if this deque contained the specified element
768 * (or equivalently, if this deque changed as a result of the call).
769 *
770 * <p>This method is equivalent to
771 * {@link #removeFirstOccurrence(Object) removeFirstOccurrence}.
772 *
773 * @param o element to be removed from this deque, if present
774 * @return {@code true} if this deque changed as a result of the call
775 */
776 public boolean remove(Object o) {
777 return removeFirstOccurrence(o);
778 }
779
780 /**
781 * Returns the number of elements in this deque.
782 *
783 * @return the number of elements in this deque
784 */
785 public int size() {
786 final ReentrantLock lock = this.lock;
787 lock.lock();
788 try {
789 return count;
790 } finally {
791 // checkInvariants();
792 lock.unlock();
793 }
794 }
795
796 /**
797 * Returns {@code true} if this deque contains the specified element.
798 * More formally, returns {@code true} if and only if this deque contains
799 * at least one element {@code e} such that {@code o.equals(e)}.
800 *
801 * @param o object to be checked for containment in this deque
802 * @return {@code true} if this deque contains the specified element
803 */
804 public boolean contains(Object o) {
805 if (o == null) return false;
806 final ReentrantLock lock = this.lock;
807 lock.lock();
808 try {
809 for (Node<E> p = first; p != null; p = p.next)
810 if (o.equals(p.item))
811 return true;
812 return false;
813 } finally {
814 // checkInvariants();
815 lock.unlock();
816 }
817 }
818
819 /**
820 * Appends all of the elements in the specified collection to the end of
821 * this deque, in the order that they are returned by the specified
822 * collection's iterator. Attempts to {@code addAll} of a deque to
823 * itself result in {@code IllegalArgumentException}.
824 *
825 * @param c the elements to be inserted into this deque
826 * @return {@code true} if this deque changed as a result of the call
827 * @throws NullPointerException if the specified collection or any
828 * of its elements are null
829 * @throws IllegalArgumentException if the collection is this deque
830 * @throws IllegalStateException if this deque is full
831 * @see #add(Object)
832 */
833 public boolean addAll(Collection<? extends E> c) {
834 if (c == this)
835 // As historically specified in AbstractQueue#addAll
836 throw new IllegalArgumentException();
837
838 // Copy c into a private chain of Nodes
839 Node<E> beg = null, end = null;
840 int n = 0;
841 for (E e : c) {
842 Objects.requireNonNull(e);
843 n++;
844 Node<E> newNode = new Node<E>(e);
845 if (beg == null)
846 beg = end = newNode;
847 else {
848 end.next = newNode;
849 newNode.prev = end;
850 end = newNode;
851 }
852 }
853 if (beg == null)
854 return false;
855
856 // Atomically append the chain at the end
857 final ReentrantLock lock = this.lock;
858 lock.lock();
859 try {
860 if (count + n <= capacity) {
861 beg.prev = last;
862 if (first == null)
863 first = beg;
864 else
865 last.next = beg;
866 last = end;
867 count += n;
868 notEmpty.signalAll();
869 return true;
870 }
871 } finally {
872 // checkInvariants();
873 lock.unlock();
874 }
875 // Fall back to historic non-atomic implementation, failing
876 // with IllegalStateException when the capacity is exceeded.
877 return super.addAll(c);
878 }
879
880 /**
881 * Returns an array containing all of the elements in this deque, in
882 * proper sequence (from first to last element).
883 *
884 * <p>The returned array will be "safe" in that no references to it are
885 * maintained by this deque. (In other words, this method must allocate
886 * a new array). The caller is thus free to modify the returned array.
887 *
888 * <p>This method acts as bridge between array-based and collection-based
889 * APIs.
890 *
891 * @return an array containing all of the elements in this deque
892 */
893 @SuppressWarnings("unchecked")
894 public Object[] toArray() {
895 final ReentrantLock lock = this.lock;
896 lock.lock();
897 try {
898 Object[] a = new Object[count];
899 int k = 0;
900 for (Node<E> p = first; p != null; p = p.next)
901 a[k++] = p.item;
902 return a;
903 } finally {
904 // checkInvariants();
905 lock.unlock();
906 }
907 }
908
909 /**
910 * Returns an array containing all of the elements in this deque, in
911 * proper sequence; the runtime type of the returned array is that of
912 * the specified array. If the deque fits in the specified array, it
913 * is returned therein. Otherwise, a new array is allocated with the
914 * runtime type of the specified array and the size of this deque.
915 *
916 * <p>If this deque fits in the specified array with room to spare
917 * (i.e., the array has more elements than this deque), the element in
918 * the array immediately following the end of the deque is set to
919 * {@code null}.
920 *
921 * <p>Like the {@link #toArray()} method, this method acts as bridge between
922 * array-based and collection-based APIs. Further, this method allows
923 * precise control over the runtime type of the output array, and may,
924 * under certain circumstances, be used to save allocation costs.
925 *
926 * <p>Suppose {@code x} is a deque known to contain only strings.
927 * The following code can be used to dump the deque into a newly
928 * allocated array of {@code String}:
929 *
930 * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
931 *
932 * Note that {@code toArray(new Object[0])} is identical in function to
933 * {@code toArray()}.
934 *
935 * @param a the array into which the elements of the deque are to
936 * be stored, if it is big enough; otherwise, a new array of the
937 * same runtime type is allocated for this purpose
938 * @return an array containing all of the elements in this deque
939 * @throws ArrayStoreException if the runtime type of the specified array
940 * is not a supertype of the runtime type of every element in
941 * this deque
942 * @throws NullPointerException if the specified array is null
943 */
944 @SuppressWarnings("unchecked")
945 public <T> T[] toArray(T[] a) {
946 final ReentrantLock lock = this.lock;
947 lock.lock();
948 try {
949 if (a.length < count)
950 a = (T[])java.lang.reflect.Array.newInstance
951 (a.getClass().getComponentType(), count);
952
953 int k = 0;
954 for (Node<E> p = first; p != null; p = p.next)
955 a[k++] = (T)p.item;
956 if (a.length > k)
957 a[k] = null;
958 return a;
959 } finally {
960 // checkInvariants();
961 lock.unlock();
962 }
963 }
964
965 public String toString() {
966 return Helpers.collectionToString(this);
967 }
968
969 /**
970 * Atomically removes all of the elements from this deque.
971 * The deque will be empty after this call returns.
972 */
973 public void clear() {
974 final ReentrantLock lock = this.lock;
975 lock.lock();
976 try {
977 for (Node<E> f = first; f != null; ) {
978 f.item = null;
979 Node<E> n = f.next;
980 f.prev = null;
981 f.next = null;
982 f = n;
983 }
984 first = last = null;
985 count = 0;
986 notFull.signalAll();
987 } finally {
988 // checkInvariants();
989 lock.unlock();
990 }
991 }
992
993 /**
994 * Used for any element traversal that is not entirely under lock.
995 * Such traversals must handle both:
996 * - dequeued nodes (p.next == p)
997 * - (possibly multiple) interior removed nodes (p.item == null)
998 */
999 Node<E> succ(Node<E> p) {
1000 if (p == (p = p.next))
1001 p = first;
1002 return p;
1003 }
1004
1005 /**
1006 * Returns an iterator over the elements in this deque in proper sequence.
1007 * The elements will be returned in order from first (head) to last (tail).
1008 *
1009 * <p>The returned iterator is
1010 * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
1011 *
1012 * @return an iterator over the elements in this deque in proper sequence
1013 */
1014 public Iterator<E> iterator() {
1015 return new Itr();
1016 }
1017
1018 /**
1019 * Returns an iterator over the elements in this deque in reverse
1020 * sequential order. The elements will be returned in order from
1021 * last (tail) to first (head).
1022 *
1023 * <p>The returned iterator is
1024 * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
1025 *
1026 * @return an iterator over the elements in this deque in reverse order
1027 */
1028 public Iterator<E> descendingIterator() {
1029 return new DescendingItr();
1030 }
1031
1032 /**
1033 * Base class for LinkedBlockingDeque iterators.
1034 */
1035 private abstract class AbstractItr implements Iterator<E> {
1036 /**
1037 * The next node to return in next().
1038 */
1039 Node<E> next;
1040
1041 /**
1042 * nextItem holds on to item fields because once we claim that
1043 * an element exists in hasNext(), we must return item read
1044 * under lock even if it was in the process of being removed
1045 * when hasNext() was called.
1046 */
1047 E nextItem;
1048
1049 /**
1050 * Node returned by most recent call to next. Needed by remove.
1051 * Reset to null if this element is deleted by a call to remove.
1052 */
1053 private Node<E> lastRet;
1054
1055 abstract Node<E> firstNode();
1056 abstract Node<E> nextNode(Node<E> n);
1057
1058 private Node<E> succ(Node<E> p) {
1059 if (p == (p = nextNode(p)))
1060 p = firstNode();
1061 return p;
1062 }
1063
1064 AbstractItr() {
1065 // set to initial position
1066 final ReentrantLock lock = LinkedBlockingDeque.this.lock;
1067 lock.lock();
1068 try {
1069 if ((next = firstNode()) != null)
1070 nextItem = next.item;
1071 } finally {
1072 // checkInvariants();
1073 lock.unlock();
1074 }
1075 }
1076
1077 public boolean hasNext() {
1078 return next != null;
1079 }
1080
1081 public E next() {
1082 Node<E> p;
1083 if ((p = next) == null)
1084 throw new NoSuchElementException();
1085 lastRet = p;
1086 E x = nextItem;
1087 final ReentrantLock lock = LinkedBlockingDeque.this.lock;
1088 lock.lock();
1089 try {
1090 E e = null;
1091 for (p = nextNode(p); p != null && (e = p.item) == null; )
1092 p = succ(p);
1093 next = p;
1094 nextItem = e;
1095 } finally {
1096 // checkInvariants();
1097 lock.unlock();
1098 }
1099 return x;
1100 }
1101
1102 public void forEachRemaining(Consumer<? super E> action) {
1103 // A variant of forEachFrom
1104 Objects.requireNonNull(action);
1105 Node<E> p;
1106 if ((p = next) == null) return;
1107 lastRet = p;
1108 next = null;
1109 final ReentrantLock lock = LinkedBlockingDeque.this.lock;
1110 final int batchSize = 32;
1111 Object[] es = null;
1112 int n, len = 1;
1113 do {
1114 lock.lock();
1115 try {
1116 if (es == null) {
1117 p = nextNode(p);
1118 for (Node<E> q = p; q != null; q = succ(q))
1119 if (q.item != null && ++len == batchSize)
1120 break;
1121 es = new Object[len];
1122 es[0] = nextItem;
1123 nextItem = null;
1124 n = 1;
1125 } else
1126 n = 0;
1127 for (; p != null && n < len; p = succ(p))
1128 if ((es[n] = p.item) != null) {
1129 lastRet = p;
1130 n++;
1131 }
1132 } finally {
1133 // checkInvariants();
1134 lock.unlock();
1135 }
1136 for (int i = 0; i < n; i++) {
1137 @SuppressWarnings("unchecked") E e = (E) es[i];
1138 action.accept(e);
1139 }
1140 } while (n > 0 && p != null);
1141 }
1142
1143 public void remove() {
1144 Node<E> n = lastRet;
1145 if (n == null)
1146 throw new IllegalStateException();
1147 lastRet = null;
1148 final ReentrantLock lock = LinkedBlockingDeque.this.lock;
1149 lock.lock();
1150 try {
1151 if (n.item != null)
1152 unlink(n);
1153 } finally {
1154 // checkInvariants();
1155 lock.unlock();
1156 }
1157 }
1158 }
1159
1160 /** Forward iterator */
1161 private class Itr extends AbstractItr {
1162 Itr() {} // prevent access constructor creation
1163 Node<E> firstNode() { return first; }
1164 Node<E> nextNode(Node<E> n) { return n.next; }
1165 }
1166
1167 /** Descending iterator */
1168 private class DescendingItr extends AbstractItr {
1169 DescendingItr() {} // prevent access constructor creation
1170 Node<E> firstNode() { return last; }
1171 Node<E> nextNode(Node<E> n) { return n.prev; }
1172 }
1173
1174 /**
1175 * A customized variant of Spliterators.IteratorSpliterator.
1176 * Keep this class in sync with (very similar) LBQSpliterator.
1177 */
1178 private final class LBDSpliterator implements Spliterator<E> {
1179 static final int MAX_BATCH = 1 << 25; // max batch array size;
1180 Node<E> current; // current node; null until initialized
1181 int batch; // batch size for splits
1182 boolean exhausted; // true when no more nodes
1183 long est = size(); // size estimate
1184
1185 LBDSpliterator() {}
1186
1187 public long estimateSize() { return est; }
1188
1189 public Spliterator<E> trySplit() {
1190 Node<E> h;
1191 if (!exhausted &&
1192 ((h = current) != null || (h = first) != null)
1193 && h.next != null) {
1194 int n = batch = Math.min(batch + 1, MAX_BATCH);
1195 Object[] a = new Object[n];
1196 final ReentrantLock lock = LinkedBlockingDeque.this.lock;
1197 int i = 0;
1198 Node<E> p = current;
1199 lock.lock();
1200 try {
1201 if (p != null || (p = first) != null)
1202 for (; p != null && i < n; p = succ(p))
1203 if ((a[i] = p.item) != null)
1204 i++;
1205 } finally {
1206 // checkInvariants();
1207 lock.unlock();
1208 }
1209 if ((current = p) == null) {
1210 est = 0L;
1211 exhausted = true;
1212 }
1213 else if ((est -= i) < 0L)
1214 est = 0L;
1215 if (i > 0)
1216 return Spliterators.spliterator
1217 (a, 0, i, (Spliterator.ORDERED |
1218 Spliterator.NONNULL |
1219 Spliterator.CONCURRENT));
1220 }
1221 return null;
1222 }
1223
1224 public boolean tryAdvance(Consumer<? super E> action) {
1225 Objects.requireNonNull(action);
1226 if (!exhausted) {
1227 E e = null;
1228 final ReentrantLock lock = LinkedBlockingDeque.this.lock;
1229 lock.lock();
1230 try {
1231 Node<E> p;
1232 if ((p = current) != null || (p = first) != null)
1233 do {
1234 e = p.item;
1235 p = succ(p);
1236 } while (e == null && p != null);
1237 if ((current = p) == null)
1238 exhausted = true;
1239 } finally {
1240 // checkInvariants();
1241 lock.unlock();
1242 }
1243 if (e != null) {
1244 action.accept(e);
1245 return true;
1246 }
1247 }
1248 return false;
1249 }
1250
1251 public void forEachRemaining(Consumer<? super E> action) {
1252 Objects.requireNonNull(action);
1253 if (!exhausted) {
1254 exhausted = true;
1255 Node<E> p = current;
1256 current = null;
1257 forEachFrom(action, p);
1258 }
1259 }
1260
1261 public int characteristics() {
1262 return (Spliterator.ORDERED |
1263 Spliterator.NONNULL |
1264 Spliterator.CONCURRENT);
1265 }
1266 }
1267
1268 /**
1269 * Returns a {@link Spliterator} over the elements in this deque.
1270 *
1271 * <p>The returned spliterator is
1272 * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
1273 *
1274 * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT},
1275 * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}.
1276 *
1277 * @implNote
1278 * The {@code Spliterator} implements {@code trySplit} to permit limited
1279 * parallelism.
1280 *
1281 * @return a {@code Spliterator} over the elements in this deque
1282 * @since 1.8
1283 */
1284 public Spliterator<E> spliterator() {
1285 return new LBDSpliterator();
1286 }
1287
1288 /**
1289 * @throws NullPointerException {@inheritDoc}
1290 */
1291 public void forEach(Consumer<? super E> action) {
1292 Objects.requireNonNull(action);
1293 forEachFrom(action, null);
1294 }
1295
1296 /**
1297 * Runs action on each element found during a traversal starting at p.
1298 * If p is null, traversal starts at head.
1299 */
1300 void forEachFrom(Consumer<? super E> action, Node<E> p) {
1301 // Extract batches of elements while holding the lock; then
1302 // run the action on the elements while not
1303 final ReentrantLock lock = this.lock;
1304 final int batchSize = 32; // max number of elements per batch
1305 Object[] es = null; // container for batch of elements
1306 int n, len = 0;
1307 do {
1308 lock.lock();
1309 try {
1310 if (es == null) {
1311 if (p == null) p = first;
1312 for (Node<E> q = p; q != null; q = succ(q))
1313 if (q.item != null && ++len == batchSize)
1314 break;
1315 es = new Object[len];
1316 }
1317 for (n = 0; p != null && n < len; p = succ(p))
1318 if ((es[n] = p.item) != null)
1319 n++;
1320 } finally {
1321 // checkInvariants();
1322 lock.unlock();
1323 }
1324 for (int i = 0; i < n; i++) {
1325 @SuppressWarnings("unchecked") E e = (E) es[i];
1326 action.accept(e);
1327 }
1328 } while (n > 0 && p != null);
1329 }
1330
1331 /**
1332 * @throws NullPointerException {@inheritDoc}
1333 */
1334 public boolean removeIf(Predicate<? super E> filter) {
1335 Objects.requireNonNull(filter);
1336 return bulkRemove(filter);
1337 }
1338
1339 /**
1340 * @throws NullPointerException {@inheritDoc}
1341 */
1342 public boolean removeAll(Collection<?> c) {
1343 Objects.requireNonNull(c);
1344 return bulkRemove(e -> c.contains(e));
1345 }
1346
1347 /**
1348 * @throws NullPointerException {@inheritDoc}
1349 */
1350 public boolean retainAll(Collection<?> c) {
1351 Objects.requireNonNull(c);
1352 return bulkRemove(e -> !c.contains(e));
1353 }
1354
1355 /** Implementation of bulk remove methods. */
1356 @SuppressWarnings("unchecked")
1357 private boolean bulkRemove(Predicate<? super E> filter) {
1358 boolean removed = false;
1359 Node<E> p = null;
1360 final ReentrantLock lock = this.lock;
1361 Node<E>[] nodes = null;
1362 int n, len = 0;
1363 do {
1364 // 1. Extract batch of up to 64 elements while holding the lock.
1365 long deathRow = 0; // "bitset" of size 64
1366 lock.lock();
1367 try {
1368 if (nodes == null) {
1369 if (p == null) p = first;
1370 for (Node<E> q = p; q != null; q = succ(q))
1371 if (q.item != null && ++len == 64)
1372 break;
1373 nodes = (Node<E>[]) new Node<?>[len];
1374 }
1375 for (n = 0; p != null && n < len; p = succ(p))
1376 nodes[n++] = p;
1377 } finally {
1378 // checkInvariants();
1379 lock.unlock();
1380 }
1381
1382 // 2. Run the filter on the elements while lock is free.
1383 for (int i = 0; i < n; i++) {
1384 final E e;
1385 if ((e = nodes[i].item) != null && filter.test(e))
1386 deathRow |= 1L << i;
1387 }
1388
1389 // 3. Remove any filtered elements while holding the lock.
1390 if (deathRow != 0) {
1391 lock.lock();
1392 try {
1393 for (int i = 0; i < n; i++) {
1394 final Node<E> q;
1395 if ((deathRow & (1L << i)) != 0L
1396 && (q = nodes[i]).item != null) {
1397 unlink(q);
1398 removed = true;
1399 }
1400 }
1401 } finally {
1402 // checkInvariants();
1403 lock.unlock();
1404 }
1405 }
1406 } while (n > 0 && p != null);
1407 return removed;
1408 }
1409
1410 /**
1411 * Saves this deque to a stream (that is, serializes it).
1412 *
1413 * @param s the stream
1414 * @throws java.io.IOException if an I/O error occurs
1415 * @serialData The capacity (int), followed by elements (each an
1416 * {@code Object}) in the proper order, followed by a null
1417 */
1418 private void writeObject(java.io.ObjectOutputStream s)
1419 throws java.io.IOException {
1420 final ReentrantLock lock = this.lock;
1421 lock.lock();
1422 try {
1423 // Write out capacity and any hidden stuff
1424 s.defaultWriteObject();
1425 // Write out all elements in the proper order.
1426 for (Node<E> p = first; p != null; p = p.next)
1427 s.writeObject(p.item);
1428 // Use trailing null as sentinel
1429 s.writeObject(null);
1430 } finally {
1431 // checkInvariants();
1432 lock.unlock();
1433 }
1434 }
1435
1436 /**
1437 * Reconstitutes this deque from a stream (that is, deserializes it).
1438 * @param s the stream
1439 * @throws ClassNotFoundException if the class of a serialized object
1440 * could not be found
1441 * @throws java.io.IOException if an I/O error occurs
1442 */
1443 private void readObject(java.io.ObjectInputStream s)
1444 throws java.io.IOException, ClassNotFoundException {
1445 s.defaultReadObject();
1446 count = 0;
1447 first = null;
1448 last = null;
1449 // Read in all elements and place in queue
1450 for (;;) {
1451 @SuppressWarnings("unchecked") E item = (E)s.readObject();
1452 if (item == null)
1453 break;
1454 add(item);
1455 }
1456 }
1457
1458 void checkInvariants() {
1459 // assert lock.isHeldByCurrentThread();
1460 // Nodes may get self-linked or lose their item, but only
1461 // after being unlinked and becoming unreachable from first.
1462 for (Node<E> p = first; p != null; p = p.next) {
1463 // assert p.next != p;
1464 // assert p.item != null;
1465 }
1466 }
1467
1468 }