diff -r 28c62f5e9a47 -r 6214297bf27d jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java --- a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Tue Jul 02 15:58:09 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Wed Jul 03 11:58:09 2013 +0200 @@ -42,6 +42,9 @@ import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Queue; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.function.Consumer; /** * An unbounded concurrent {@linkplain Deque deque} based on linked nodes. @@ -816,7 +819,7 @@ * Creates an array list and fills it with elements of this list. * Used by toArray. * - * @return the arrayList + * @return the array list */ private ArrayList toArrayList() { ArrayList list = new ArrayList(); @@ -1024,11 +1027,27 @@ } public E poll() { return pollFirst(); } + public E peek() { return peekFirst(); } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ public E remove() { return removeFirst(); } - public E peek() { return peekFirst(); } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E pop() { return removeFirst(); } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ public E element() { return getFirst(); } + + /** + * @throws NullPointerException {@inheritDoc} + */ public void push(E e) { addFirst(e); } - public E pop() { return removeFirst(); } /** * Removes the first element {@code e} such that @@ -1385,6 +1404,99 @@ Node nextNode(Node p) { return pred(p); } } + /** A customized variant of Spliterators.IteratorSpliterator */ + static final class CLDSpliterator implements Spliterator { + static final int MAX_BATCH = 1 << 25; // max batch array size; + final ConcurrentLinkedDeque queue; + Node current; // current node; null until initialized + int batch; // batch size for splits + boolean exhausted; // true when no more nodes + CLDSpliterator(ConcurrentLinkedDeque queue) { + this.queue = queue; + } + + public Spliterator trySplit() { + Node p; + final ConcurrentLinkedDeque q = this.queue; + int b = batch; + int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1; + if (!exhausted && + ((p = current) != null || (p = q.first()) != null)) { + if (p.item == null && p == (p = p.next)) + current = p = q.first(); + if (p != null && p.next != null) { + Object[] a = new Object[n]; + int i = 0; + do { + if ((a[i] = p.item) != null) + ++i; + if (p == (p = p.next)) + p = q.first(); + } while (p != null && i < n); + if ((current = p) == null) + exhausted = true; + if (i > 0) { + batch = i; + return Spliterators.spliterator + (a, 0, i, Spliterator.ORDERED | Spliterator.NONNULL | + Spliterator.CONCURRENT); + } + } + } + return null; + } + + public void forEachRemaining(Consumer action) { + Node p; + if (action == null) throw new NullPointerException(); + final ConcurrentLinkedDeque q = this.queue; + if (!exhausted && + ((p = current) != null || (p = q.first()) != null)) { + exhausted = true; + do { + E e = p.item; + if (p == (p = p.next)) + p = q.first(); + if (e != null) + action.accept(e); + } while (p != null); + } + } + + public boolean tryAdvance(Consumer action) { + Node p; + if (action == null) throw new NullPointerException(); + final ConcurrentLinkedDeque q = this.queue; + if (!exhausted && + ((p = current) != null || (p = q.first()) != null)) { + E e; + do { + e = p.item; + if (p == (p = p.next)) + p = q.first(); + } while (e == null && p != null); + if ((current = p) == null) + exhausted = true; + if (e != null) { + action.accept(e); + return true; + } + } + return false; + } + + public long estimateSize() { return Long.MAX_VALUE; } + + public int characteristics() { + return Spliterator.ORDERED | Spliterator.NONNULL | + Spliterator.CONCURRENT; + } + } + + public Spliterator spliterator() { + return new CLDSpliterator(this); + } + /** * Saves this deque to a stream (that is, serializes it). *