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