src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java
changeset 47340 83f933b97787
parent 47216 71c04702a3d5
child 47729 1563167c9520
equal deleted inserted replaced
47339:186868cadb5d 47340:83f933b97787
   229      * to check whether we have reached a TERMINATOR node; if so,
   229      * to check whether we have reached a TERMINATOR node; if so,
   230      * restart traversal from tail.
   230      * restart traversal from tail.
   231      *
   231      *
   232      * The implementation is completely directionally symmetrical,
   232      * The implementation is completely directionally symmetrical,
   233      * except that most public methods that iterate through the list
   233      * except that most public methods that iterate through the list
   234      * follow next pointers ("forward" direction).
   234      * follow next pointers, in the "forward" direction.
   235      *
   235      *
   236      * We believe (without full proof) that all single-element deque
   236      * We believe (without full proof) that all single-element Deque
   237      * operations (e.g., addFirst, peekLast, pollLast) are linearizable
   237      * operations that operate directly at the two ends of the Deque
   238      * (see Herlihy and Shavit's book).  However, some combinations of
   238      * (e.g., addFirst, peekLast, pollLast) are linearizable (see
       
   239      * Herlihy and Shavit's book).  However, some combinations of
   239      * operations are known not to be linearizable.  In particular,
   240      * operations are known not to be linearizable.  In particular,
   240      * when an addFirst(A) is racing with pollFirst() removing B, it is
   241      * when an addFirst(A) is racing with pollFirst() removing B, it
   241      * possible for an observer iterating over the elements to observe
   242      * is possible for an observer iterating over the elements to
   242      * A B C and subsequently observe A C, even though no interior
   243      * observe first [A B C] and then [A C], even though no interior
   243      * removes are ever performed.  Nevertheless, iterators behave
   244      * removes are ever performed.  Nevertheless, iterators behave
   244      * reasonably, providing the "weakly consistent" guarantees.
   245      * reasonably, providing the "weakly consistent" guarantees.
   245      *
   246      *
   246      * Empirically, microbenchmarks suggest that this class adds about
   247      * Empirically, microbenchmarks suggest that this class adds about
   247      * 40% overhead relative to ConcurrentLinkedQueue, which feels as
   248      * 40% overhead relative to ConcurrentLinkedQueue, which feels as
   863         linkLast(e);
   864         linkLast(e);
   864         return true;
   865         return true;
   865     }
   866     }
   866 
   867 
   867     public E peekFirst() {
   868     public E peekFirst() {
   868         for (Node<E> p = first(); p != null; p = succ(p)) {
   869         restart: for (;;) {
   869             final E item;
   870             for (Node<E> first = first(), p = first;;) {
   870             if ((item = p.item) != null)
   871                 final E item;
   871                 return item;
   872                 if ((item = p.item) != null) {
   872         }
   873                     // recheck for linearizability
   873         return null;
   874                     if (first.prev != null) continue restart;
       
   875                     return item;
       
   876                 }
       
   877                 if ((p = succ(p)) == null)
       
   878                     return null;
       
   879             }
       
   880         }
   874     }
   881     }
   875 
   882 
   876     public E peekLast() {
   883     public E peekLast() {
   877         for (Node<E> p = last(); p != null; p = pred(p)) {
   884         restart: for (;;) {
   878             final E item;
   885             for (Node<E> last = last(), p = last;;) {
   879             if ((item = p.item) != null)
   886                 final E item;
   880                 return item;
   887                 if ((item = p.item) != null) {
   881         }
   888                     // recheck for linearizability
   882         return null;
   889                     if (last.next != null) continue restart;
       
   890                     return item;
       
   891                 }
       
   892                 if ((p = pred(p)) == null)
       
   893                     return null;
       
   894             }
       
   895         }
   883     }
   896     }
   884 
   897 
   885     /**
   898     /**
   886      * @throws NoSuchElementException {@inheritDoc}
   899      * @throws NoSuchElementException {@inheritDoc}
   887      */
   900      */
   895     public E getLast() {
   908     public E getLast() {
   896         return screenNullResult(peekLast());
   909         return screenNullResult(peekLast());
   897     }
   910     }
   898 
   911 
   899     public E pollFirst() {
   912     public E pollFirst() {
   900         for (Node<E> p = first(); p != null; p = succ(p)) {
   913         restart: for (;;) {
   901             final E item;
   914             for (Node<E> first = first(), p = first;;) {
   902             if ((item = p.item) != null
   915                 final E item;
   903                 && ITEM.compareAndSet(p, item, null)) {
   916                 if ((item = p.item) != null) {
   904                 unlink(p);
   917                     // recheck for linearizability
   905                 return item;
   918                     if (first.prev != null) continue restart;
   906             }
   919                     if (ITEM.compareAndSet(p, item, null)) {
   907         }
   920                         unlink(p);
   908         return null;
   921                         return item;
       
   922                     }
       
   923                 }
       
   924                 if ((p = succ(p)) == null)
       
   925                     return null;
       
   926             }
       
   927         }
   909     }
   928     }
   910 
   929 
   911     public E pollLast() {
   930     public E pollLast() {
   912         for (Node<E> p = last(); p != null; p = pred(p)) {
   931         restart: for (;;) {
   913             final E item;
   932             for (Node<E> last = last(), p = last;;) {
   914             if ((item = p.item) != null
   933                 final E item;
   915                 && ITEM.compareAndSet(p, item, null)) {
   934                 if ((item = p.item) != null) {
   916                 unlink(p);
   935                     // recheck for linearizability
   917                 return item;
   936                     if (last.next != null) continue restart;
   918             }
   937                     if (ITEM.compareAndSet(p, item, null)) {
   919         }
   938                         unlink(p);
   920         return null;
   939                         return item;
       
   940                     }
       
   941                 }
       
   942                 if ((p = pred(p)) == null)
       
   943                     return null;
       
   944             }
       
   945         }
   921     }
   946     }
   922 
   947 
   923     /**
   948     /**
   924      * @throws NoSuchElementException {@inheritDoc}
   949      * @throws NoSuchElementException {@inheritDoc}
   925      */
   950      */
  1077      * useful in concurrent applications.
  1102      * useful in concurrent applications.
  1078      *
  1103      *
  1079      * @return the number of elements in this deque
  1104      * @return the number of elements in this deque
  1080      */
  1105      */
  1081     public int size() {
  1106     public int size() {
  1082         restartFromHead: for (;;) {
  1107         restart: for (;;) {
  1083             int count = 0;
  1108             int count = 0;
  1084             for (Node<E> p = first(); p != null;) {
  1109             for (Node<E> p = first(); p != null;) {
  1085                 if (p.item != null)
  1110                 if (p.item != null)
  1086                     if (++count == Integer.MAX_VALUE)
  1111                     if (++count == Integer.MAX_VALUE)
  1087                         break;  // @see Collection.size()
  1112                         break;  // @see Collection.size()
  1088                 if (p == (p = p.next))
  1113                 if (p == (p = p.next))
  1089                     continue restartFromHead;
  1114                     continue restart;
  1090             }
  1115             }
  1091             return count;
  1116             return count;
  1092         }
  1117         }
  1093     }
  1118     }
  1094 
  1119 
  1181             ;
  1206             ;
  1182     }
  1207     }
  1183 
  1208 
  1184     public String toString() {
  1209     public String toString() {
  1185         String[] a = null;
  1210         String[] a = null;
  1186         restartFromHead: for (;;) {
  1211         restart: for (;;) {
  1187             int charLength = 0;
  1212             int charLength = 0;
  1188             int size = 0;
  1213             int size = 0;
  1189             for (Node<E> p = first(); p != null;) {
  1214             for (Node<E> p = first(); p != null;) {
  1190                 final E item;
  1215                 final E item;
  1191                 if ((item = p.item) != null) {
  1216                 if ((item = p.item) != null) {
  1196                     String s = item.toString();
  1221                     String s = item.toString();
  1197                     a[size++] = s;
  1222                     a[size++] = s;
  1198                     charLength += s.length();
  1223                     charLength += s.length();
  1199                 }
  1224                 }
  1200                 if (p == (p = p.next))
  1225                 if (p == (p = p.next))
  1201                     continue restartFromHead;
  1226                     continue restart;
  1202             }
  1227             }
  1203 
  1228 
  1204             if (size == 0)
  1229             if (size == 0)
  1205                 return "[]";
  1230                 return "[]";
  1206 
  1231 
  1208         }
  1233         }
  1209     }
  1234     }
  1210 
  1235 
  1211     private Object[] toArrayInternal(Object[] a) {
  1236     private Object[] toArrayInternal(Object[] a) {
  1212         Object[] x = a;
  1237         Object[] x = a;
  1213         restartFromHead: for (;;) {
  1238         restart: for (;;) {
  1214             int size = 0;
  1239             int size = 0;
  1215             for (Node<E> p = first(); p != null;) {
  1240             for (Node<E> p = first(); p != null;) {
  1216                 final E item;
  1241                 final E item;
  1217                 if ((item = p.item) != null) {
  1242                 if ((item = p.item) != null) {
  1218                     if (x == null)
  1243                     if (x == null)
  1220                     else if (size == x.length)
  1245                     else if (size == x.length)
  1221                         x = Arrays.copyOf(x, 2 * (size + 4));
  1246                         x = Arrays.copyOf(x, 2 * (size + 4));
  1222                     x[size++] = item;
  1247                     x[size++] = item;
  1223                 }
  1248                 }
  1224                 if (p == (p = p.next))
  1249                 if (p == (p = p.next))
  1225                     continue restartFromHead;
  1250                     continue restart;
  1226             }
  1251             }
  1227             if (x == null)
  1252             if (x == null)
  1228                 return new Object[0];
  1253                 return new Object[0];
  1229             else if (a != null && size <= a.length) {
  1254             else if (a != null && size <= a.length) {
  1230                 if (a != x)
  1255                 if (a != x)