jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java
changeset 16883 8c290711866f
parent 13018 92c86cea72a8
child 17717 fe0b28a1a3bd
equal deleted inserted replaced
16882:c9b0f63bb215 16883:8c290711866f
    32  * Expert Group and released to the public domain, as explained at
    32  * Expert Group and released to the public domain, as explained at
    33  * http://creativecommons.org/publicdomain/zero/1.0/
    33  * http://creativecommons.org/publicdomain/zero/1.0/
    34  */
    34  */
    35 
    35 
    36 package java.util.concurrent;
    36 package java.util.concurrent;
       
    37 import java.io.ObjectInputStream;
    37 import java.util.concurrent.locks.*;
    38 import java.util.concurrent.locks.*;
    38 import java.util.*;
    39 import java.util.*;
    39 import java.io.Serializable;
    40 import java.io.Serializable;
    40 
    41 
    41 /**
    42 /**
  1481      * @param s the stream
  1482      * @param s the stream
  1482      */
  1483      */
  1483     @SuppressWarnings("unchecked")
  1484     @SuppressWarnings("unchecked")
  1484     private void readObject(java.io.ObjectInputStream s)
  1485     private void readObject(java.io.ObjectInputStream s)
  1485             throws java.io.IOException, ClassNotFoundException {
  1486             throws java.io.IOException, ClassNotFoundException {
  1486         s.defaultReadObject();
  1487         // Don't call defaultReadObject()
       
  1488         ObjectInputStream.GetField oisFields = s.readFields();
       
  1489         final Segment<K,V>[] oisSegments = (Segment<K,V>[])oisFields.get("segments", null);
       
  1490 
       
  1491         final int ssize = oisSegments.length;
       
  1492         if (ssize < 1 || ssize > MAX_SEGMENTS
       
  1493             || (ssize & (ssize-1)) != 0 )  // ssize not power of two
       
  1494             throw new java.io.InvalidObjectException("Bad number of segments:"
       
  1495                                                      + ssize);
       
  1496         int sshift = 0, ssizeTmp = ssize;
       
  1497         while (ssizeTmp > 1) {
       
  1498             ++sshift;
       
  1499             ssizeTmp >>>= 1;
       
  1500         }
       
  1501         UNSAFE.putIntVolatile(this, SEGSHIFT_OFFSET, 32 - sshift);
       
  1502         UNSAFE.putIntVolatile(this, SEGMASK_OFFSET, ssize - 1);
       
  1503         UNSAFE.putObjectVolatile(this, SEGMENTS_OFFSET, oisSegments);
  1487 
  1504 
  1488         // set hashMask
  1505         // set hashMask
  1489         UNSAFE.putIntVolatile(this, HASHSEED_OFFSET,
  1506         UNSAFE.putIntVolatile(this, HASHSEED_OFFSET,
  1490                  sun.misc.Hashing.randomHashSeed(this));
  1507                  sun.misc.Hashing.randomHashSeed(this));
  1491 
  1508 
  1515     private static final long SBASE;
  1532     private static final long SBASE;
  1516     private static final int SSHIFT;
  1533     private static final int SSHIFT;
  1517     private static final long TBASE;
  1534     private static final long TBASE;
  1518     private static final int TSHIFT;
  1535     private static final int TSHIFT;
  1519     private static final long HASHSEED_OFFSET;
  1536     private static final long HASHSEED_OFFSET;
       
  1537     private static final long SEGSHIFT_OFFSET;
       
  1538     private static final long SEGMASK_OFFSET;
       
  1539     private static final long SEGMENTS_OFFSET;
  1520 
  1540 
  1521     static {
  1541     static {
  1522         int ss, ts;
  1542         int ss, ts;
  1523         try {
  1543         try {
  1524             UNSAFE = sun.misc.Unsafe.getUnsafe();
  1544             UNSAFE = sun.misc.Unsafe.getUnsafe();
  1528             SBASE = UNSAFE.arrayBaseOffset(sc);
  1548             SBASE = UNSAFE.arrayBaseOffset(sc);
  1529             ts = UNSAFE.arrayIndexScale(tc);
  1549             ts = UNSAFE.arrayIndexScale(tc);
  1530             ss = UNSAFE.arrayIndexScale(sc);
  1550             ss = UNSAFE.arrayIndexScale(sc);
  1531             HASHSEED_OFFSET = UNSAFE.objectFieldOffset(
  1551             HASHSEED_OFFSET = UNSAFE.objectFieldOffset(
  1532                 ConcurrentHashMap.class.getDeclaredField("hashSeed"));
  1552                 ConcurrentHashMap.class.getDeclaredField("hashSeed"));
       
  1553             SEGSHIFT_OFFSET = UNSAFE.objectFieldOffset(
       
  1554                 ConcurrentHashMap.class.getDeclaredField("segmentShift"));
       
  1555             SEGMASK_OFFSET = UNSAFE.objectFieldOffset(
       
  1556                 ConcurrentHashMap.class.getDeclaredField("segmentMask"));
       
  1557             SEGMENTS_OFFSET = UNSAFE.objectFieldOffset(
       
  1558                 ConcurrentHashMap.class.getDeclaredField("segments"));
  1533         } catch (Exception e) {
  1559         } catch (Exception e) {
  1534             throw new Error(e);
  1560             throw new Error(e);
  1535         }
  1561         }
  1536         if ((ss & (ss-1)) != 0 || (ts & (ts-1)) != 0)
  1562         if ((ss & (ss-1)) != 0 || (ts & (ts-1)) != 0)
  1537             throw new Error("data type scale not a power of two");
  1563             throw new Error("data type scale not a power of two");