ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentLinkedQueue.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/ConcurrentLinkedQueue.java (file contents):
Revision 1.50 by jsr166, Wed Jul 29 17:42:28 2009 UTC vs.
Revision 1.51 by jsr166, Wed Jul 29 17:47:05 2009 UTC

# Line 5 | Line 5
5   */
6  
7   package java.util.concurrent;
8 import java.util.*;
9 import java.util.concurrent.atomic.*;
8  
9 + import java.util.AbstractQueue;
10 + import java.util.ArrayList;
11 + import java.util.Collection;
12 + import java.util.Iterator;
13 + import java.util.NoSuchElementException;
14 + import java.util.Queue;
15  
16   /**
17   * An unbounded thread-safe {@linkplain Queue queue} based on linked nodes.
# Line 126 | Line 130 | public class ConcurrentLinkedQueue<E> ex
130       * CAS, so they never regress, although again this is merely an
131       * optimization.
132       */
133 +
134      private static class Node<E> {
135          private volatile E item;
136          private volatile Node<E> next;
137  
138 <        Node(E item) { lazySetItem(item); }
138 >        Node(E item) {
139 >            // Piggyback on imminent casNext()
140 >            lazySetItem(item);
141 >        }
142  
143          E getItem() {
144              return item;
# Line 171 | Line 179 | public class ConcurrentLinkedQueue<E> ex
179      }
180  
181      /**
182 <     * Pointer to first node, initialized to a dummy node.
182 >     * A node from which the first live (non-deleted) node (if any)
183 >     * can be reached in O(1) time.
184 >     * Invariants:
185 >     * - all live nodes are reachable from head via succ()
186 >     * - head != null
187 >     * - (tmp = head).next != tmp || tmp != head
188 >     * Non-invariants:
189 >     * - head.item may or may not be null.
190 >     * - it is permitted for tail to lag behind head, that is, for tail
191 >     *   to not be reachable from head!
192       */
193      private transient volatile Node<E> head = new Node<E>(null);
194  
195 <    /** Pointer to last node on list */
195 >    /**
196 >     * A node from which the last node on list (that is, the unique
197 >     * node with node.next == null) can be reached in O(1) time.
198 >     * Invariants:
199 >     * - the last node is always reachable from tail via succ()
200 >     * - tail != null
201 >     * Non-invariants:
202 >     * - tail.item may or may not be null.
203 >     * - it is permitted for tail to lag behind head, that is, for tail
204 >     *   to not be reachable from head!
205 >     * - tail.next may or may not be self-pointing to tail.
206 >     */
207      private transient volatile Node<E> tail = head;
208  
209  
# Line 210 | Line 238 | public class ConcurrentLinkedQueue<E> ex
238      }
239  
240      /**
241 <     * We don't bother to update head or tail pointers if less than
241 >     * We don't bother to update head or tail pointers if fewer than
242       * HOPS links from "true" location.  We assume that volatile
243       * writes are significantly more expensive than volatile reads.
244       */
# Line 307 | Line 335 | public class ConcurrentLinkedQueue<E> ex
335      }
336  
337      /**
338 <     * Returns the first actual (non-header) node on list.  This is yet
339 <     * another variant of poll/peek; here returning out the first
340 <     * node, not element (so we cannot collapse with peek() without
341 <     * introducing race.)
338 >     * Returns the first live (non-deleted) node on list, or null if none.
339 >     * This is yet another variant of poll/peek; here returning the
340 >     * first node, not element.  We could make peek() a wrapper around
341 >     * first(), but that would cost an extra volatile read of item,
342 >     * and the need to add a retry loop to deal with the possibility
343 >     * of losing a race to a concurrent poll().
344       */
345      Node<E> first() {
346          Node<E> h = head;
# Line 401 | Line 431 | public class ConcurrentLinkedQueue<E> ex
431          Node<E> pred = null;
432          for (Node<E> p = first(); p != null; p = succ(p)) {
433              E item = p.getItem();
434 <            if (item != null && o.equals(item) && p.casItem(item, null)) {
434 >            if (item != null &&
435 >                o.equals(item) &&
436 >                p.casItem(item, null)) {
437                  Node<E> next = succ(p);
438                  if (pred != null && next != null)
439                      pred.casNext(p, next);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines