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

Comparing jsr166/src/main/java/util/concurrent/ConcurrentHashMap.java (file contents):
Revision 1.278 by jsr166, Sat Sep 12 21:55:08 2015 UTC vs.
Revision 1.297 by jsr166, Mon Aug 22 18:38:27 2016 UTC

# Line 39 | Line 39 | import java.util.function.ToIntFunction;
39   import java.util.function.ToLongBiFunction;
40   import java.util.function.ToLongFunction;
41   import java.util.stream.Stream;
42 + import jdk.internal.misc.Unsafe;
43  
44   /**
45   * A hash table supporting full concurrency of retrievals and
# Line 133 | Line 134 | import java.util.stream.Stream;
134   * setValue}.
135   *
136   * <ul>
137 < * <li> forEach: Perform a given action on each element.
137 > * <li>forEach: Performs a given action on each element.
138   * A variant form applies a given transformation on each element
139 < * before performing the action.</li>
139 > * before performing the action.
140   *
141 < * <li> search: Return the first available non-null result of
141 > * <li>search: Returns the first available non-null result of
142   * applying a given function on each element; skipping further
143 < * search when a result is found.</li>
143 > * search when a result is found.
144   *
145 < * <li> reduce: Accumulate each element.  The supplied reduction
145 > * <li>reduce: Accumulates each element.  The supplied reduction
146   * function cannot rely on ordering (more formally, it should be
147   * both associative and commutative).  There are five variants:
148   *
149   * <ul>
150   *
151 < * <li> Plain reductions. (There is not a form of this method for
151 > * <li>Plain reductions. (There is not a form of this method for
152   * (key, value) function arguments since there is no corresponding
153 < * return type.)</li>
153 > * return type.)
154   *
155 < * <li> Mapped reductions that accumulate the results of a given
156 < * function applied to each element.</li>
155 > * <li>Mapped reductions that accumulate the results of a given
156 > * function applied to each element.
157   *
158 < * <li> Reductions to scalar doubles, longs, and ints, using a
159 < * given basis value.</li>
158 > * <li>Reductions to scalar doubles, longs, and ints, using a
159 > * given basis value.
160   *
161   * </ul>
161 * </li>
162   * </ul>
163   *
164   * <p>These bulk operations accept a {@code parallelismThreshold}
# Line 269 | Line 269 | public class ConcurrentHashMap<K,V> exte
269       * Table accesses require volatile/atomic reads, writes, and
270       * CASes.  Because there is no other way to arrange this without
271       * adding further indirections, we use intrinsics
272 <     * (sun.misc.Unsafe) operations.
272 >     * (jdk.internal.misc.Unsafe) operations.
273       *
274       * We use the top (sign) bit of Node hash fields for control
275       * purposes -- it is available anyway because of addressing
# Line 544 | Line 544 | public class ConcurrentHashMap<K,V> exte
544       * The number of bits used for generation stamp in sizeCtl.
545       * Must be at least 6 for 32bit arrays.
546       */
547 <    private static int RESIZE_STAMP_BITS = 16;
547 >    private static final int RESIZE_STAMP_BITS = 16;
548  
549      /**
550       * The maximum number of threads that can help resize.
# Line 568 | Line 568 | public class ConcurrentHashMap<K,V> exte
568      /** Number of CPUS, to place bounds on some sizings */
569      static final int NCPU = Runtime.getRuntime().availableProcessors();
570  
571 <    /** For serialization compatibility. */
571 >    /**
572 >     * Serialized pseudo-fields, provided only for jdk7 compatibility.
573 >     * @serialField segments Segment[]
574 >     *   The segments, each of which is a specialized hash table.
575 >     * @serialField segmentMask int
576 >     *   Mask value for indexing into segments. The upper bits of a
577 >     *   key's hash code are used to choose the segment.
578 >     * @serialField segmentShift int
579 >     *   Shift value for indexing within segments.
580 >     */
581      private static final ObjectStreamField[] serialPersistentFields = {
582          new ObjectStreamField("segments", Segment[].class),
583          new ObjectStreamField("segmentMask", Integer.TYPE),
584 <        new ObjectStreamField("segmentShift", Integer.TYPE)
584 >        new ObjectStreamField("segmentShift", Integer.TYPE),
585      };
586  
587      /* ---------------- Nodes -------------- */
# Line 591 | Line 600 | public class ConcurrentHashMap<K,V> exte
600          volatile V val;
601          volatile Node<K,V> next;
602  
603 <        Node(int hash, K key, V val, Node<K,V> next) {
603 >        Node(int hash, K key, V val) {
604              this.hash = hash;
605              this.key = key;
606              this.val = val;
607 +        }
608 +
609 +        Node(int hash, K key, V val, Node<K,V> next) {
610 +            this(hash, key, val);
611              this.next = next;
612          }
613  
# Line 706 | Line 719 | public class ConcurrentHashMap<K,V> exte
719      /* ---------------- Table element access -------------- */
720  
721      /*
722 <     * Volatile access methods are used for table elements as well as
722 >     * Atomic access methods are used for table elements as well as
723       * elements of in-progress next table while resizing.  All uses of
724       * the tab arguments must be null checked by callers.  All callers
725       * also paranoically precheck that tab's length is not zero (or an
# Line 716 | Line 729 | public class ConcurrentHashMap<K,V> exte
729       * errors by users, these checks must operate on local variables,
730       * which accounts for some odd-looking inline assignments below.
731       * Note that calls to setTabAt always occur within locked regions,
732 <     * and so in principle require only release ordering, not
720 <     * full volatile semantics, but are currently coded as volatile
721 <     * writes to be conservative.
732 >     * and so require only release ordering.
733       */
734  
735      @SuppressWarnings("unchecked")
736      static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) {
737 <        return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE);
737 >        return (Node<K,V>)U.getObjectAcquire(tab, ((long)i << ASHIFT) + ABASE);
738      }
739  
740      static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i,
# Line 732 | Line 743 | public class ConcurrentHashMap<K,V> exte
743      }
744  
745      static final <K,V> void setTabAt(Node<K,V>[] tab, int i, Node<K,V> v) {
746 <        U.putObjectVolatile(tab, ((long)i << ASHIFT) + ABASE, v);
746 >        U.putObjectRelease(tab, ((long)i << ASHIFT) + ABASE, v);
747      }
748  
749      /* ---------------- Fields -------------- */
# Line 983 | Line 994 | public class ConcurrentHashMap<K,V> exte
994          int hash = spread(key.hashCode());
995          int binCount = 0;
996          for (Node<K,V>[] tab = table;;) {
997 <            Node<K,V> f; int n, i, fh;
997 >            Node<K,V> f; int n, i, fh; K fk; V fv;
998              if (tab == null || (n = tab.length) == 0)
999                  tab = initTable();
1000              else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
1001 <                if (casTabAt(tab, i, null,
991 <                             new Node<K,V>(hash, key, value, null)))
1001 >                if (casTabAt(tab, i, null, new Node<K,V>(hash, key, value)))
1002                      break;                   // no lock when adding to empty bin
1003              }
1004              else if ((fh = f.hash) == MOVED)
1005                  tab = helpTransfer(tab, f);
1006 +            else if (onlyIfAbsent && fh == hash &&  // check first node
1007 +                     ((fk = f.key) == key || fk != null && key.equals(fk)) &&
1008 +                     (fv = f.val) != null)
1009 +                return fv;
1010              else {
1011                  V oldVal = null;
1012                  synchronized (f) {
# Line 1011 | Line 1025 | public class ConcurrentHashMap<K,V> exte
1025                                  }
1026                                  Node<K,V> pred = e;
1027                                  if ((e = e.next) == null) {
1028 <                                    pred.next = new Node<K,V>(hash, key,
1015 <                                                              value, null);
1028 >                                    pred.next = new Node<K,V>(hash, key, value);
1029                                      break;
1030                                  }
1031                              }
# Line 1203 | Line 1216 | public class ConcurrentHashMap<K,V> exte
1216       */
1217      public KeySetView<K,V> keySet() {
1218          KeySetView<K,V> ks;
1219 <        return (ks = keySet) != null ? ks : (keySet = new KeySetView<K,V>(this, null));
1219 >        if ((ks = keySet) != null) return ks;
1220 >        return keySet = new KeySetView<K,V>(this, null);
1221      }
1222  
1223      /**
# Line 1226 | Line 1240 | public class ConcurrentHashMap<K,V> exte
1240       */
1241      public Collection<V> values() {
1242          ValuesView<K,V> vs;
1243 <        return (vs = values) != null ? vs : (values = new ValuesView<K,V>(this));
1243 >        if ((vs = values) != null) return vs;
1244 >        return values = new ValuesView<K,V>(this);
1245      }
1246  
1247      /**
# Line 1248 | Line 1263 | public class ConcurrentHashMap<K,V> exte
1263       */
1264      public Set<Map.Entry<K,V>> entrySet() {
1265          EntrySetView<K,V> es;
1266 <        return (es = entrySet) != null ? es : (entrySet = new EntrySetView<K,V>(this));
1266 >        if ((es = entrySet) != null) return es;
1267 >        return entrySet = new EntrySetView<K,V>(this);
1268      }
1269  
1270      /**
# Line 1340 | Line 1356 | public class ConcurrentHashMap<K,V> exte
1356  
1357      /**
1358       * Stripped-down version of helper class used in previous version,
1359 <     * declared for the sake of serialization compatibility
1359 >     * declared for the sake of serialization compatibility.
1360       */
1361      static class Segment<K,V> extends ReentrantLock implements Serializable {
1362          private static final long serialVersionUID = 2249069246763182397L;
# Line 1354 | Line 1370 | public class ConcurrentHashMap<K,V> exte
1370       * @param s the stream
1371       * @throws java.io.IOException if an I/O error occurs
1372       * @serialData
1373 <     * the key (Object) and value (Object)
1374 <     * for each key-value mapping, followed by a null pair.
1373 >     * the serialized fields, followed by the key (Object) and value
1374 >     * (Object) for each key-value mapping, followed by a null pair.
1375       * The key-value mappings are emitted in no particular order.
1376       */
1377      private void writeObject(java.io.ObjectOutputStream s)
# Line 1391 | Line 1407 | public class ConcurrentHashMap<K,V> exte
1407          }
1408          s.writeObject(null);
1409          s.writeObject(null);
1394        segments = null; // throw away
1410      }
1411  
1412      /**
# Line 1595 | Line 1610 | public class ConcurrentHashMap<K,V> exte
1610      }
1611  
1612      /**
1613 <     * Helper method for EntrySetView.removeIf
1613 >     * Helper method for EntrySetView.removeIf.
1614       */
1615      boolean removeEntryIf(Predicate<? super Entry<K,V>> function) {
1616          if (function == null) throw new NullPointerException();
# Line 1615 | Line 1630 | public class ConcurrentHashMap<K,V> exte
1630      }
1631  
1632      /**
1633 <     * Helper method for ValuesView.removeIf
1633 >     * Helper method for ValuesView.removeIf.
1634       */
1635      boolean removeValueIf(Predicate<? super V> function) {
1636          if (function == null) throw new NullPointerException();
# Line 1662 | Line 1677 | public class ConcurrentHashMap<K,V> exte
1677          V val = null;
1678          int binCount = 0;
1679          for (Node<K,V>[] tab = table;;) {
1680 <            Node<K,V> f; int n, i, fh;
1680 >            Node<K,V> f; int n, i, fh; K fk; V fv;
1681              if (tab == null || (n = tab.length) == 0)
1682                  tab = initTable();
1683              else if ((f = tabAt(tab, i = (n - 1) & h)) == null) {
# Line 1673 | Line 1688 | public class ConcurrentHashMap<K,V> exte
1688                          Node<K,V> node = null;
1689                          try {
1690                              if ((val = mappingFunction.apply(key)) != null)
1691 <                                node = new Node<K,V>(h, key, val, null);
1691 >                                node = new Node<K,V>(h, key, val);
1692                          } finally {
1693                              setTabAt(tab, i, node);
1694                          }
# Line 1684 | Line 1699 | public class ConcurrentHashMap<K,V> exte
1699              }
1700              else if ((fh = f.hash) == MOVED)
1701                  tab = helpTransfer(tab, f);
1702 +            else if (fh == h &&                  // check first node
1703 +                     ((fk = f.key) == key || fk != null && key.equals(fk)) &&
1704 +                     (fv = f.val) != null)
1705 +                return fv;
1706              else {
1707                  boolean added = false;
1708                  synchronized (f) {
# Line 1704 | Line 1723 | public class ConcurrentHashMap<K,V> exte
1723                                          if (pred.next != null)
1724                                              throw new IllegalStateException("Recursive update");
1725                                          added = true;
1726 <                                        pred.next = new Node<K,V>(h, key, val, null);
1726 >                                        pred.next = new Node<K,V>(h, key, val);
1727                                      }
1728                                      break;
1729                                  }
# Line 1873 | Line 1892 | public class ConcurrentHashMap<K,V> exte
1892                          try {
1893                              if ((val = remappingFunction.apply(key, null)) != null) {
1894                                  delta = 1;
1895 <                                node = new Node<K,V>(h, key, val, null);
1895 >                                node = new Node<K,V>(h, key, val);
1896                              }
1897                          } finally {
1898                              setTabAt(tab, i, node);
# Line 1915 | Line 1934 | public class ConcurrentHashMap<K,V> exte
1934                                          if (pred.next != null)
1935                                              throw new IllegalStateException("Recursive update");
1936                                          delta = 1;
1937 <                                        pred.next =
1919 <                                            new Node<K,V>(h, key, val, null);
1937 >                                        pred.next = new Node<K,V>(h, key, val);
1938                                      }
1939                                      break;
1940                                  }
# Line 1994 | Line 2012 | public class ConcurrentHashMap<K,V> exte
2012              if (tab == null || (n = tab.length) == 0)
2013                  tab = initTable();
2014              else if ((f = tabAt(tab, i = (n - 1) & h)) == null) {
2015 <                if (casTabAt(tab, i, null, new Node<K,V>(h, key, value, null))) {
2015 >                if (casTabAt(tab, i, null, new Node<K,V>(h, key, value))) {
2016                      delta = 1;
2017                      val = value;
2018                      break;
# Line 2029 | Line 2047 | public class ConcurrentHashMap<K,V> exte
2047                                  if ((e = e.next) == null) {
2048                                      delta = 1;
2049                                      val = value;
2050 <                                    pred.next =
2033 <                                        new Node<K,V>(h, key, val, null);
2050 >                                    pred.next = new Node<K,V>(h, key, val);
2051                                      break;
2052                                  }
2053                              }
# Line 2081 | Line 2098 | public class ConcurrentHashMap<K,V> exte
2098       * <p>Note that this method is identical in functionality to
2099       * {@link #containsValue(Object)}, and exists solely to ensure
2100       * full compatibility with class {@link java.util.Hashtable},
2101 <     * which supported this method prior to introduction of the Java
2102 <     * Collections Framework.
2101 >     * which supported this method prior to introduction of the
2102 >     * Java Collections Framework.
2103       *
2104       * @param  value a value to search for
2105       * @return {@code true} if and only if some key maps to the
# Line 2191 | Line 2208 | public class ConcurrentHashMap<K,V> exte
2208      static final class ForwardingNode<K,V> extends Node<K,V> {
2209          final Node<K,V>[] nextTable;
2210          ForwardingNode(Node<K,V>[] tab) {
2211 <            super(MOVED, null, null, null);
2211 >            super(MOVED, null, null);
2212              this.nextTable = tab;
2213          }
2214  
# Line 2223 | Line 2240 | public class ConcurrentHashMap<K,V> exte
2240      }
2241  
2242      /**
2243 <     * A place-holder node used in computeIfAbsent and compute
2243 >     * A place-holder node used in computeIfAbsent and compute.
2244       */
2245      static final class ReservationNode<K,V> extends Node<K,V> {
2246          ReservationNode() {
2247 <            super(RESERVED, null, null, null);
2247 >            super(RESERVED, null, null);
2248          }
2249  
2250          Node<K,V> find(int h, Object k) {
# Line 2522 | Line 2539 | public class ConcurrentHashMap<K,V> exte
2539       * A padded cell for distributing counts.  Adapted from LongAdder
2540       * and Striped64.  See their internal docs for explanation.
2541       */
2542 <    @sun.misc.Contended static final class CounterCell {
2542 >    @jdk.internal.vm.annotation.Contended static final class CounterCell {
2543          volatile long value;
2544          CounterCell(long x) { value = x; }
2545      }
# Line 2654 | Line 2671 | public class ConcurrentHashMap<K,V> exte
2671      }
2672  
2673      /**
2674 <     * Returns a list on non-TreeNodes replacing those in given list.
2674 >     * Returns a list of non-TreeNodes replacing those in given list.
2675       */
2676      static <K,V> Node<K,V> untreeify(Node<K,V> b) {
2677          Node<K,V> hd = null, tl = null;
2678          for (Node<K,V> q = b; q != null; q = q.next) {
2679 <            Node<K,V> p = new Node<K,V>(q.hash, q.key, q.val, null);
2679 >            Node<K,V> p = new Node<K,V>(q.hash, q.key, q.val);
2680              if (tl == null)
2681                  hd = p;
2682              else
# Line 2672 | Line 2689 | public class ConcurrentHashMap<K,V> exte
2689      /* ---------------- TreeNodes -------------- */
2690  
2691      /**
2692 <     * Nodes for use in TreeBins
2692 >     * Nodes for use in TreeBins.
2693       */
2694      static final class TreeNode<K,V> extends Node<K,V> {
2695          TreeNode<K,V> parent;  // red-black tree links
# Line 2765 | Line 2782 | public class ConcurrentHashMap<K,V> exte
2782           * Creates bin with initial set of nodes headed by b.
2783           */
2784          TreeBin(TreeNode<K,V> b) {
2785 <            super(TREEBIN, null, null, null);
2785 >            super(TREEBIN, null, null);
2786              this.first = b;
2787              TreeNode<K,V> r = null;
2788              for (TreeNode<K,V> x = b, next; x != null; x = next) {
# Line 3235 | Line 3252 | public class ConcurrentHashMap<K,V> exte
3252          }
3253  
3254          /**
3255 <         * Recursive invariant check
3255 >         * Checks invariants recursively for the tree of Nodes rooted at t.
3256           */
3257          static <K,V> boolean checkInvariants(TreeNode<K,V> t) {
3258              TreeNode<K,V> tp = t.parent, tl = t.left, tr = t.right,
# Line 3259 | Line 3276 | public class ConcurrentHashMap<K,V> exte
3276              return true;
3277          }
3278  
3279 <        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
3279 >        private static final Unsafe U = Unsafe.getUnsafe();
3280          private static final long LOCKSTATE;
3281          static {
3282              try {
# Line 3480 | Line 3497 | public class ConcurrentHashMap<K,V> exte
3497      }
3498  
3499      /**
3500 <     * Exported Entry for EntryIterator
3500 >     * Exported Entry for EntryIterator.
3501       */
3502      static final class MapEntry<K,V> implements Map.Entry<K,V> {
3503          final K key; // non-null
# Line 3533 | Line 3550 | public class ConcurrentHashMap<K,V> exte
3550              this.est = est;
3551          }
3552  
3553 <        public Spliterator<K> trySplit() {
3553 >        public KeySpliterator<K,V> trySplit() {
3554              int i, f, h;
3555              return (h = ((i = baseIndex) + (f = baseLimit)) >>> 1) <= i ? null :
3556                  new KeySpliterator<K,V>(tab, baseSize, baseLimit = h,
# Line 3572 | Line 3589 | public class ConcurrentHashMap<K,V> exte
3589              this.est = est;
3590          }
3591  
3592 <        public Spliterator<V> trySplit() {
3592 >        public ValueSpliterator<K,V> trySplit() {
3593              int i, f, h;
3594              return (h = ((i = baseIndex) + (f = baseLimit)) >>> 1) <= i ? null :
3595                  new ValueSpliterator<K,V>(tab, baseSize, baseLimit = h,
# Line 3612 | Line 3629 | public class ConcurrentHashMap<K,V> exte
3629              this.est = est;
3630          }
3631  
3632 <        public Spliterator<Map.Entry<K,V>> trySplit() {
3632 >        public EntrySpliterator<K,V> trySplit() {
3633              int i, f, h;
3634              return (h = ((i = baseIndex) + (f = baseLimit)) >>> 1) <= i ? null :
3635                  new EntrySpliterator<K,V>(tab, baseSize, baseLimit = h,
# Line 4424 | Line 4441 | public class ConcurrentHashMap<K,V> exte
4441          public abstract boolean contains(Object o);
4442          public abstract boolean remove(Object o);
4443  
4444 <        private static final String oomeMsg = "Required array size too large";
4444 >        private static final String OOME_MSG = "Required array size too large";
4445  
4446          public final Object[] toArray() {
4447              long sz = map.mappingCount();
4448              if (sz > MAX_ARRAY_SIZE)
4449 <                throw new OutOfMemoryError(oomeMsg);
4449 >                throw new OutOfMemoryError(OOME_MSG);
4450              int n = (int)sz;
4451              Object[] r = new Object[n];
4452              int i = 0;
4453              for (E e : this) {
4454                  if (i == n) {
4455                      if (n >= MAX_ARRAY_SIZE)
4456 <                        throw new OutOfMemoryError(oomeMsg);
4456 >                        throw new OutOfMemoryError(OOME_MSG);
4457                      if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
4458                          n = MAX_ARRAY_SIZE;
4459                      else
# Line 4452 | Line 4469 | public class ConcurrentHashMap<K,V> exte
4469          public final <T> T[] toArray(T[] a) {
4470              long sz = map.mappingCount();
4471              if (sz > MAX_ARRAY_SIZE)
4472 <                throw new OutOfMemoryError(oomeMsg);
4472 >                throw new OutOfMemoryError(OOME_MSG);
4473              int m = (int)sz;
4474              T[] r = (a.length >= m) ? a :
4475                  (T[])java.lang.reflect.Array
# Line 4462 | Line 4479 | public class ConcurrentHashMap<K,V> exte
4479              for (E e : this) {
4480                  if (i == n) {
4481                      if (n >= MAX_ARRAY_SIZE)
4482 <                        throw new OutOfMemoryError(oomeMsg);
4482 >                        throw new OutOfMemoryError(OOME_MSG);
4483                      if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
4484                          n = MAX_ARRAY_SIZE;
4485                      else
# Line 4515 | Line 4532 | public class ConcurrentHashMap<K,V> exte
4532              return true;
4533          }
4534  
4535 <        public final boolean removeAll(Collection<?> c) {
4535 >        public boolean removeAll(Collection<?> c) {
4536              if (c == null) throw new NullPointerException();
4537              boolean modified = false;
4538 <            for (Iterator<E> it = iterator(); it.hasNext();) {
4539 <                if (c.contains(it.next())) {
4540 <                    it.remove();
4541 <                    modified = true;
4538 >            // Use (c instanceof Set) as a hint that lookup in c is as
4539 >            // efficient as this view
4540 >            Node<K,V>[] t;
4541 >            if ((t = map.table) == null) {
4542 >                return false;
4543 >            } else if (c instanceof Set<?> && c.size() > t.length) {
4544 >                for (Iterator<?> it = iterator(); it.hasNext(); ) {
4545 >                    if (c.contains(it.next())) {
4546 >                        it.remove();
4547 >                        modified = true;
4548 >                    }
4549                  }
4550 +            } else {
4551 +                for (Object e : c)
4552 +                    modified |= remove(e);
4553              }
4554              return modified;
4555          }
# Line 4709 | Line 4736 | public class ConcurrentHashMap<K,V> exte
4736              throw new UnsupportedOperationException();
4737          }
4738  
4739 +        @Override public boolean removeAll(Collection<?> c) {
4740 +            if (c == null) throw new NullPointerException();
4741 +            boolean modified = false;
4742 +            for (Iterator<V> it = iterator(); it.hasNext();) {
4743 +                if (c.contains(it.next())) {
4744 +                    it.remove();
4745 +                    modified = true;
4746 +                }
4747 +            }
4748 +            return modified;
4749 +        }
4750 +
4751          public boolean removeIf(Predicate<? super V> filter) {
4752              return map.removeValueIf(filter);
4753          }
# Line 4857 | Line 4896 | public class ConcurrentHashMap<K,V> exte
4896          }
4897  
4898          /**
4899 <         * Same as Traverser version
4899 >         * Same as Traverser version.
4900           */
4901          final Node<K,V> advance() {
4902              Node<K,V> e;
# Line 6302 | Line 6341 | public class ConcurrentHashMap<K,V> exte
6341      }
6342  
6343      // Unsafe mechanics
6344 <    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
6344 >    private static final Unsafe U = Unsafe.getUnsafe();
6345      private static final long SIZECTL;
6346      private static final long TRANSFERINDEX;
6347      private static final long BASECOUNT;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines