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.306 by jsr166, Sun Jan 7 21:53:40 2018 UTC vs.
Revision 1.318 by jsr166, Sat Aug 10 16:48:05 2019 UTC

# Line 224 | Line 224 | import jdk.internal.misc.Unsafe;
224   * <p>All arguments to all task methods must be non-null.
225   *
226   * <p>This class is a member of the
227 < * <a href="{@docRoot}/java/util/package-summary.html#CollectionsFramework">
227 > * <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">
228   * Java Collections Framework</a>.
229   *
230   * @since 1.5
# Line 356 | Line 356 | public class ConcurrentHashMap<K,V> exte
356       * cases where old nodes can be reused because their next fields
357       * won't change.  On average, only about one-sixth of them need
358       * cloning when a table doubles. The nodes they replace will be
359 <     * garbage collectable as soon as they are no longer referenced by
359 >     * garbage collectible as soon as they are no longer referenced by
360       * any reader thread that may be in the midst of concurrently
361       * traversing table.  Upon transfer, the old table bin contains
362       * only a special forwarding node (with hash field "MOVED") that
# Line 673 | Line 673 | public class ConcurrentHashMap<K,V> exte
673       * See Hackers Delight, sec 3.2
674       */
675      private static final int tableSizeFor(int c) {
676 <        int n = c - 1;
677 <        n |= n >>> 1;
678 <        n |= n >>> 2;
679 <        n |= n >>> 4;
680 <        n |= n >>> 8;
681 <        n |= n >>> 16;
676 >        int n = -1 >>> Integer.numberOfLeadingZeros(c - 1);
677          return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
678      }
679  
# Line 815 | Line 810 | public class ConcurrentHashMap<K,V> exte
810       * elements is negative
811       */
812      public ConcurrentHashMap(int initialCapacity) {
813 <        if (initialCapacity < 0)
819 <            throw new IllegalArgumentException();
820 <        int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ?
821 <                   MAXIMUM_CAPACITY :
822 <                   tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1));
823 <        this.sizeCtl = cap;
813 >        this(initialCapacity, LOAD_FACTOR, 1);
814      }
815  
816      /**
# Line 854 | Line 844 | public class ConcurrentHashMap<K,V> exte
844  
845      /**
846       * Creates a new, empty map with an initial table size based on
847 <     * the given number of elements ({@code initialCapacity}), table
848 <     * density ({@code loadFactor}), and number of concurrently
847 >     * the given number of elements ({@code initialCapacity}), initial
848 >     * table density ({@code loadFactor}), and number of concurrently
849       * updating threads ({@code concurrencyLevel}).
850       *
851       * @param initialCapacity the initial capacity. The implementation
# Line 1444 | Line 1434 | public class ConcurrentHashMap<K,V> exte
1434          if (size == 0L)
1435              sizeCtl = 0;
1436          else {
1437 <            int n;
1438 <            if (size >= (long)(MAXIMUM_CAPACITY >>> 1))
1439 <                n = MAXIMUM_CAPACITY;
1450 <            else {
1451 <                int sz = (int)size;
1452 <                n = tableSizeFor(sz + (sz >>> 1) + 1);
1453 <            }
1437 >            long ts = (long)(1.0 + size / LOAD_FACTOR);
1438 >            int n = (ts >= (long)MAXIMUM_CAPACITY) ?
1439 >                MAXIMUM_CAPACITY : tableSizeFor((int)ts);
1440              @SuppressWarnings("unchecked")
1441              Node<K,V>[] tab = (Node<K,V>[])new Node<?,?>[n];
1442              int mask = n - 1;
# Line 2319 | Line 2305 | public class ConcurrentHashMap<K,V> exte
2305              Node<K,V>[] tab, nt; int n, sc;
2306              while (s >= (long)(sc = sizeCtl) && (tab = table) != null &&
2307                     (n = tab.length) < MAXIMUM_CAPACITY) {
2308 <                int rs = resizeStamp(n);
2308 >                int rs = resizeStamp(n) << RESIZE_STAMP_SHIFT;
2309                  if (sc < 0) {
2310 <                    if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||
2311 <                        sc == rs + MAX_RESIZERS || (nt = nextTable) == null ||
2326 <                        transferIndex <= 0)
2310 >                    if (sc == rs + MAX_RESIZERS || sc == rs + 1 ||
2311 >                        (nt = nextTable) == null || transferIndex <= 0)
2312                          break;
2313                      if (U.compareAndSetInt(this, SIZECTL, sc, sc + 1))
2314                          transfer(tab, nt);
2315                  }
2316 <                else if (U.compareAndSetInt(this, SIZECTL, sc,
2332 <                                             (rs << RESIZE_STAMP_SHIFT) + 2))
2316 >                else if (U.compareAndSetInt(this, SIZECTL, sc, rs + 2))
2317                      transfer(tab, null);
2318                  s = sumCount();
2319              }
# Line 2343 | Line 2327 | public class ConcurrentHashMap<K,V> exte
2327          Node<K,V>[] nextTab; int sc;
2328          if (tab != null && (f instanceof ForwardingNode) &&
2329              (nextTab = ((ForwardingNode<K,V>)f).nextTable) != null) {
2330 <            int rs = resizeStamp(tab.length);
2330 >            int rs = resizeStamp(tab.length) << RESIZE_STAMP_SHIFT;
2331              while (nextTab == nextTable && table == tab &&
2332                     (sc = sizeCtl) < 0) {
2333 <                if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||
2334 <                    sc == rs + MAX_RESIZERS || transferIndex <= 0)
2333 >                if (sc == rs + MAX_RESIZERS || sc == rs + 1 ||
2334 >                    transferIndex <= 0)
2335                      break;
2336                  if (U.compareAndSetInt(this, SIZECTL, sc, sc + 1)) {
2337                      transfer(tab, nextTab);
# Line 2527 | Line 2511 | public class ConcurrentHashMap<K,V> exte
2511                              setTabAt(tab, i, fwd);
2512                              advance = true;
2513                          }
2514 +                        else if (f instanceof ReservationNode)
2515 +                            throw new IllegalStateException("Recursive update");
2516                      }
2517                  }
2518              }
# Line 3272 | Line 3258 | public class ConcurrentHashMap<K,V> exte
3258          }
3259  
3260          private static final Unsafe U = Unsafe.getUnsafe();
3261 <        private static final long LOCKSTATE;
3262 <        static {
3277 <            try {
3278 <                LOCKSTATE = U.objectFieldOffset
3279 <                    (TreeBin.class.getDeclaredField("lockState"));
3280 <            } catch (ReflectiveOperationException e) {
3281 <                throw new Error(e);
3282 <            }
3283 <        }
3261 >        private static final long LOCKSTATE
3262 >                = U.objectFieldOffset(TreeBin.class, "lockState");
3263      }
3264  
3265      /* ----------------Table Traversal -------------- */
# Line 6346 | Line 6325 | public class ConcurrentHashMap<K,V> exte
6325      private static final int ASHIFT;
6326  
6327      static {
6328 <        try {
6329 <            SIZECTL = U.objectFieldOffset
6330 <                (ConcurrentHashMap.class.getDeclaredField("sizeCtl"));
6331 <            TRANSFERINDEX = U.objectFieldOffset
6332 <                (ConcurrentHashMap.class.getDeclaredField("transferIndex"));
6333 <            BASECOUNT = U.objectFieldOffset
6334 <                (ConcurrentHashMap.class.getDeclaredField("baseCount"));
6335 <            CELLSBUSY = U.objectFieldOffset
6336 <                (ConcurrentHashMap.class.getDeclaredField("cellsBusy"));
6337 <
6338 <            CELLVALUE = U.objectFieldOffset
6339 <                (CounterCell.class.getDeclaredField("value"));
6340 <
6341 <            ABASE = U.arrayBaseOffset(Node[].class);
6342 <            int scale = U.arrayIndexScale(Node[].class);
6343 <            if ((scale & (scale - 1)) != 0)
6344 <                throw new Error("array index scale not a power of two");
6366 <            ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
6367 <        } catch (ReflectiveOperationException e) {
6368 <            throw new Error(e);
6369 <        }
6328 >        SIZECTL = U.objectFieldOffset
6329 >            (ConcurrentHashMap.class, "sizeCtl");
6330 >        TRANSFERINDEX = U.objectFieldOffset
6331 >            (ConcurrentHashMap.class, "transferIndex");
6332 >        BASECOUNT = U.objectFieldOffset
6333 >            (ConcurrentHashMap.class, "baseCount");
6334 >        CELLSBUSY = U.objectFieldOffset
6335 >            (ConcurrentHashMap.class, "cellsBusy");
6336 >
6337 >        CELLVALUE = U.objectFieldOffset
6338 >            (CounterCell.class, "value");
6339 >
6340 >        ABASE = U.arrayBaseOffset(Node[].class);
6341 >        int scale = U.arrayIndexScale(Node[].class);
6342 >        if ((scale & (scale - 1)) != 0)
6343 >            throw new ExceptionInInitializerError("array index scale not a power of two");
6344 >        ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
6345  
6346          // Reduce the risk of rare disastrous classloading in first call to
6347          // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773
6348          Class<?> ensureLoaded = LockSupport.class;
6349 +
6350 +        // Eager class load observed to help JIT during startup
6351 +        ensureLoaded = ReservationNode.class;
6352      }
6353   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines