ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/LinkedBlockingDeque.java
Revision: 1.83
Committed: Thu Oct 17 01:51:38 2019 UTC (4 years, 7 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.82: +2 -0 lines
Log Message:
8232230: Suppress warnings on non-serializable non-transient instance fields in java.util.concurrent

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