ConcurrentHashMap深入剖析(基於JDK1.7)

2022-06-28 15:02:28
近有點時間,翻了翻ConcurrentHashMap的原始碼學習了一下,對我自己認為比較重要的一些方法進行了學習,新增了一些必要的註釋,拿出來與園子的小夥伴分享一下,有說的不對的地方,還請各位批評指正,歡迎交流。
話不多說,上原始碼:
   1 package cn.com.pep.concurrent;
   2 
   3 import java.util.concurrent.ConcurrentMap;
   4 import java.util.concurrent.locks.*;
   5 
   6 import java.util.*;
   7 import java.io.Serializable;
   8 import java.io.IOException;
   9 
  10 /**
  11  * A hash table supporting full concurrency of retrievals and adjustable
  12  * expected concurrency for updates. This class obeys the same functional
  13  * specification as {@link java.util.Hashtable}, and includes versions of
  14  * methods corresponding to each method of <tt>Hashtable</tt>. However, even
  15  * though all operations are thread-safe, retrieval operations do <em>not</em>
  16  * entail locking, and there is <em>not</em> any support for locking the entire
  17  * table in a way that prevents all access. This class is fully interoperable
  18  * with <tt>Hashtable</tt> in programs that rely on its thread safety but not on
  19  * its synchronization details.
  20  *
  21  * <p>
  22  * Retrieval operations (including <tt>get</tt>) generally do not block, so may
  23  * overlap with update operations (including <tt>put</tt> and <tt>remove</tt>).
  24  * Retrievals reflect the results of the most recently <em>completed</em> update
  25  * operations holding upon their onset. For aggregate operations such as
  26  * <tt>putAll</tt> and <tt>clear</tt>, concurrent retrievals may reflect
  27  * insertion or removal of only some entries. Similarly, Iterators and
  28  * Enumerations return elements reflecting the state of the hash table at some
  29  * point at or since the creation of the iterator/enumeration. They do
  30  * <em>not</em> throw {@link ConcurrentModificationException}. However,
  31  * iterators are designed to be used by only one thread at a time.
  32  *
  33  * <p>
  34  * The allowed concurrency among update operations is guided by the optional
  35  * <tt>concurrencyLevel</tt> constructor argument (default <tt>16</tt>), which
  36  * is used as a hint for internal sizing. The table is internally partitioned to
  37  * try to permit the indicated number of concurrent updates without contention.
  38  * Because placement in hash tables is essentially random, the actual
  39  * concurrency will vary. Ideally, you should choose a value to accommodate as
  40  * many threads as will ever concurrently modify the table. Using a
  41  * significantly higher value than you need can waste space and time, and a
  42  * significantly lower value can lead to thread contention. But overestimates
  43  * and underestimates within an order of magnitude do not usually have much
  44  * noticeable impact. A value of one is appropriate when it is known that only
  45  * one thread will modify and all others will only read. Also, resizing this or
  46  * any other kind of hash table is a relatively slow operation, so, when
  47  * possible, it is a good idea to provide estimates of expected table sizes in
  48  * constructors.
  49  *
  50  * <p>
  51  * This class and its views and iterators implement all of the <em>optional</em>
  52  * methods of the {@link Map} and {@link Iterator} interfaces.
  53  *
  54  * <p>
  55  * Like {@link Hashtable} but unlike {@link HashMap}, this class does
  56  * <em>not</em> allow <tt>null</tt> to be used as a key or value.
  57  *
  58  * <p>
  59  * This class is a member of the
  60  * <a href="{@docRoot}/../technotes/guides/collections/index.html"> Java
  61  * Collections Framework</a>.
  62  *
  63  * @since 1.5
  64  * @author Doug Lea
  65  * @param <K> the type of keys maintained by this map
  66  * @param <V> the type of mapped values
  67  */
  68 public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>, Serializable {
  69     private static final long serialVersionUID = 7249069246763182397L;
  70 
  71     /*
  72      * The basic strategy is to subdivide the table among Segments, each of which
  73      * itself is a concurrently readable hash table. To reduce footprint, all but
  74      * one segments are constructed only when first needed (see ensureSegment). To
  75      * maintain visibility in the presence of lazy construction, accesses to
  76      * segments as well as elements of segment's table must use volatile access,
  77      * which is done via Unsafe within methods segmentAt etc below. These provide
  78      * the functionality of AtomicReferenceArrays but reduce the levels of
  79      * indirection. Additionally, volatile-writes of table elements and entry "next"
  80      * fields within locked operations use the cheaper "lazySet" forms of writes
  81      * (via putOrderedObject) because these writes are always followed by lock
  82      * releases that maintain sequential consistency of table updates.
  83      *
  84      * Historical note: The previous version of this class relied heavily on "final"
  85      * fields, which avoided some volatile reads at the expense of a large initial
  86      * footprint. Some remnants of that design (including forced construction of
  87      * segment 0) exist to ensure serialization compatibility.
  88      */
  89 
  90     /* ---------------- Constants -------------- */
  91 
  92     /**
  93      * The default initial capacity for this table, used when not otherwise
  94      * specified in a constructor.
  95      */
  96     static final int DEFAULT_INITIAL_CAPACITY = 16;
  97 
  98     /**
  99      * The default load factor for this table, used when not otherwise specified in
 100      * a constructor.
 101      */
 102     static final float DEFAULT_LOAD_FACTOR = 0.75f;
 103 
 104     /**
 105      * The default concurrency level for this table, used when not otherwise
 106      * specified in a constructor.
 107      */
 108     static final int DEFAULT_CONCURRENCY_LEVEL = 16;
 109 
 110     /**
 111      * The maximum capacity, used if a higher value is implicitly specified by
 112      * either of the constructors with arguments. MUST be a power of two <= 1<<30 to
 113      * ensure that entries are indexable using ints.
 114      */
 115     static final int MAXIMUM_CAPACITY = 1 << 30;
 116 
 117     /**
 118      * The minimum capacity for per-segment tables. Must be a power of two, at least
 119      * two to avoid immediate resizing on next use after lazy construction.
 120      */
 121     static final int MIN_SEGMENT_TABLE_CAPACITY = 2;
 122 
 123     /**
 124      * The maximum number of segments to allow; used to bound constructor arguments.
 125      * Must be power of two less than 1 << 24.
 126      */
 127     static final int MAX_SEGMENTS = 1 << 16; // slightly conservative
 128 
 129     /**
 130      * Number of unsynchronized retries in size and containsValue methods before
 131      * resorting to locking. This is used to avoid unbounded retries if tables
 132      * undergo continuous modification which would make it impossible to obtain an
 133      * accurate result.
 134      */
 135     static final int RETRIES_BEFORE_LOCK = 2;
 136 
 137     /* ---------------- Fields -------------- */
 138 
 139     /**
 140      * holds values which can't be initialized until after VM is booted.
 141      */
 142     private static class Holder {
 143 
 144         /**
 145          * Enable alternative hashing of String keys?
 146          *
 147          * <p>
 148          * Unlike the other hash map implementations we do not implement a threshold for
 149          * regulating whether alternative hashing is used for String keys. Alternative
 150          * hashing is either enabled for all instances or disabled for all instances.
 151          */
 152         static final boolean ALTERNATIVE_HASHING;
 153 
 154         static {
 155             // Use the "threshold" system property even though our threshold
 156             // behaviour is "ON" or "OFF".
 157             String altThreshold = java.security.AccessController
 158                     .doPrivileged(new sun.security.action.GetPropertyAction("jdk.map.althashing.threshold"));
 159 
 160             int threshold;
 161             try {
 162                 threshold = (null != altThreshold) ? Integer.parseInt(altThreshold) : Integer.MAX_VALUE;
 163 
 164                 // disable alternative hashing if -1
 165                 if (threshold == -1) {
 166                     threshold = Integer.MAX_VALUE;
 167                 }
 168 
 169                 if (threshold < 0) {
 170                     throw new IllegalArgumentException("value must be positive integer.");
 171                 }
 172             } catch (IllegalArgumentException failed) {
 173                 throw new Error("Illegal value for 'jdk.map.althashing.threshold'", failed);
 174             }
 175             ALTERNATIVE_HASHING = threshold <= MAXIMUM_CAPACITY;
 176         }
 177     }
 178 
 179     /**
 180      * A randomizing value associated with this instance that is applied to hash
 181      * code of keys to make hash collisions harder to find.
 182      */
 183     private transient final int hashSeed = randomHashSeed(this);
 184 
 185     private static int randomHashSeed(ConcurrentHashMap instance) {
 186         if (sun.misc.VM.isBooted() && Holder.ALTERNATIVE_HASHING) {
 187             return sun.misc.Hashing.randomHashSeed(instance);
 188         }
 189 
 190         return 0;
 191     }
 192 
 193     /**
 194      * Mask value for indexing into segments. The upper bits of a key's hash code
 195      * are used to choose the segment.
 196      */
 197     final int segmentMask;
 198 
 199     /**
 200      * Shift value for indexing within segments.
 201      */
 202     final int segmentShift;
 203 
 204     /**
 205      * The segments, each of which is a specialized hash table.
 206      */
 207     final Segment<K, V>[] segments;
 208 
 209     transient Set<K> keySet;
 210     transient Set<Map.Entry<K, V>> entrySet;
 211     transient Collection<V> values;
 212 
 213     /**
 214      * ConcurrentHashMap list entry. Note that this is never exported out as a
 215      * user-visible Map.Entry.
 216      */
 217     static final class HashEntry<K, V> {
 218         final int hash;
 219         final K key;
 220         volatile V value;
 221         volatile HashEntry<K, V> next;
 222 
 223         HashEntry(int hash, K key, V value, HashEntry<K, V> next) {
 224             this.hash = hash;
 225             this.key = key;
 226             this.value = value;
 227             this.next = next;
 228         }
 229 
 230         /**
 231          * Sets next field with volatile write semantics. (See above about use of
 232          * putOrderedObject.)
 233          */
 234         final void setNext(HashEntry<K, V> n) {
 235             UNSAFE.putOrderedObject(this, nextOffset, n);
 236         }
 237 
 238         // Unsafe mechanics
 239         static final sun.misc.Unsafe UNSAFE;
 240         static final long nextOffset;
 241         static {
 242             try {
 243                 UNSAFE = sun.misc.Unsafe.getUnsafe();
 244                 Class k = HashEntry.class;
 245                 nextOffset = UNSAFE.objectFieldOffset(k.getDeclaredField("next"));
 246             } catch (Exception e) {
 247                 throw new Error(e);
 248             }
 249         }
 250     }
 251 
 252     /**
 253      * Gets the ith element of given table (if nonnull) with volatile read
 254      * semantics. Note: This is manually integrated into a few performance-sensitive
 255      * methods to reduce call overhead.
 256      */
 257     @SuppressWarnings("unchecked")
 258     static final <K, V> HashEntry<K, V> entryAt(HashEntry<K, V>[] tab, int i) {
 259         /* 獲取HashEntry陣列中,指定下標的頭結點 */
 260         return (HashEntry<K, V>) (tab == null ? null : UNSAFE.getObjectVolatile(tab, i << TSHIFT + TBASE));
 261     }
 262 
 263     /**
 264      * Sets the ith element of given table, with volatile write semantics. (See
 265      * above about use of putOrderedObject.)
 266      */
 267     static final <K, V> void setEntryAt(HashEntry<K, V>[] tab, int i, HashEntry<K, V> e) {
 268         UNSAFE.putOrderedObject(tab, (i << TSHIFT) + TBASE, e);
 269     }
 270 
 271     /**
 272      * Applies a supplemental hash function to a given hashCode, which defends
 273      * against poor quality hash functions. This is critical because
 274      * ConcurrentHashMap uses power-of-two length hash tables, that otherwise
 275      * encounter collisions for hashCodes that do not differ in lower or upper bits.
 276      */
 277     private int hash(Object k) {
 278         int h = hashSeed;
 279 
 280         if ((0 != h) && (k instanceof String)) {
 281             return sun.misc.Hashing.stringHash32((String) k);
 282         }
 283 
 284         h ^= k.hashCode();
 285 
 286         // Spread bits to regularize both segment and index locations,
 287         // using variant of single-word Wang/Jenkins hash.
 288         h += (h << 15) ^ 0xffffcd7d;
 289         h ^= (h >>> 10);
 290         h += (h << 3);
 291         h ^= (h >>> 6);
 292         h += (h << 2) + (h << 14);
 293         return h ^ (h >>> 16);
 294     }
 295 
 296     /**
 297      * Segments are specialized versions of hash tables. This subclasses from
 298      * ReentrantLock opportunistically, just to simplify some locking and avoid
 299      * separate construction.
 300      */
 301     static final class Segment<K, V> extends ReentrantLock implements Serializable {
 302         /*
 303          * Segments maintain a table of entry lists that are always kept in a consistent
 304          * state, so can be read (via volatile reads of segments and tables) without
 305          * locking. This requires replicating nodes when necessary during table
 306          * resizing, so the old lists can be traversed by readers still using old
 307          * version of table.
 308          *
 309          * This class defines only mutative methods requiring locking. Except as noted,
 310          * the methods of this class perform the per-segment versions of
 311          * ConcurrentHashMap methods. (Other methods are integrated directly into
 312          * ConcurrentHashMap methods.) These mutative methods use a form of controlled
 313          * spinning on contention via methods scanAndLock and scanAndLockForPut. These
 314          * intersperse tryLocks with traversals to locate nodes. The main benefit is to
 315          * absorb cache misses (which are very common for hash tables) while obtaining
 316          * locks so that traversal is faster once acquired. We do not actually use the
 317          * found nodes since they must be re-acquired under lock anyway to ensure
 318          * sequential consistency of updates (and in any case may be undetectably
 319          * stale), but they will normally be much faster to re-locate. Also,
 320          * scanAndLockForPut speculatively creates a fresh node to use in put if no node
 321          * is found.
 322          */
 323 
 324         private static final long serialVersionUID = 2249069246763182397L;
 325 
 326         /**
 327          * The maximum number of times to tryLock in a prescan before possibly blocking
 328          * on acquire in preparation for a locked segment operation. On multiprocessors,
 329          * using a bounded number of retries maintains cache acquired while locating
 330          * nodes.
 331          */
 332         static final int MAX_SCAN_RETRIES = Runtime.getRuntime().availableProcessors() > 1 ? 64 : 1;
 333 
 334         /**
 335          * The per-segment table. Elements are accessed via entryAt/setEntryAt providing
 336          * volatile semantics.
 337          */
 338         transient volatile HashEntry<K, V>[] table;
 339 
 340         /**
 341          * The number of elements. Accessed only either within locks or among other
 342          * volatile reads that maintain visibility.
 343          */
 344         transient int count;//當前segment中包含節點元素的數量
 345 
 346         /**
 347          * The total number of mutative operations in this segment. Even though this may
 348          * overflows 32 bits, it provides sufficient accuracy for stability checks in
 349          * CHM isEmpty() and size() methods. Accessed only either within locks or among
 350          * other volatile reads that maintain visibility.
 351          */
 352         transient int modCount;//發生寫操作的次數
 353 
 354         /**
 355          * The table is rehashed when its size exceeds this threshold. (The value of
 356          * this field is always <tt>(int)(capacity *
 357          * loadFactor)</tt>.)
 358          */
 359         transient int threshold;//進行擴容的閾值
 360 
 361         /**
 362          * The load factor for the hash table. Even though this value is same for all
 363          * segments, it is replicated to avoid needing links to outer object.
 364          * 
 365          * @serial
 366          */
 367         final float loadFactor;//載入因子
 368 
 369         Segment(float lf, int threshold, HashEntry<K, V>[] tab) {
 370             this.loadFactor = lf;
 371             this.threshold = threshold;
 372             this.table = tab;
 373         }
 374 
 375         final V put(K key, int hash, V value, boolean onlyIfAbsent) {
 376             /* Try get lock for synchronized */
 377             HashEntry<K, V> node = tryLock() ? null : scanAndLockForPut(key, hash, value);
 378             V oldValue = null;
 379             try {
 380                 HashEntry<K, V>[] tab = table;
 381                 int index = (tab.length - 1) & hash;
 382                 /* 獲取頭結點 */
 383                 HashEntry<K, V> first = entryAt(tab, index);
 384                 for (HashEntry<K, V> e = first;;) {
 385                     if (e != null) {
 386                         K k;
 387                         if ((k = e.key) == key || (e.hash == hash && key.equals(k))) {
 388                             oldValue = e.value;
 389                             if (!onlyIfAbsent) {
 390                                 e.value = value;
 391                                 ++modCount;
 392                             }
 393                             break;
 394                         }
 395                         e = e.next;
 396                     } else {
 397                         /* 獲取鎖的過程中,建立了node節點,將node直接連結到當前這條鏈的頭結點,作為新的頭結點 */
 398                         if (node != null) {
 399                             node.next = first;
 400                         } else {
 401                             /* 否則,建立新的頭結點 */
 402                             node = new HashEntry<K, V>(hash, key, value, first);
 403                         }
 404 
 405                         int c = count + 1;
 406                         /* 判斷是否需要重新當前Segment中的陣列是否需要重新hash */
 407                         if (c > threshold && tab.length < MAXIMUM_CAPACITY) {
 408                             rehash(node);
 409                         } else {
 410                             setEntryAt(tab, index, node);
 411                         }
 412                         ++modCount;
 413                         count = c;
 414                         oldValue = null;
 415                         break;
 416                     }
 417                 }
 418             } finally {
 419                 unlock();
 420             }
 421 
 422             return oldValue;
 423         }
 424 
 425         /**
 426          * Doubles size of table and repacks entries, also adding the given node to new
 427          * table
 428          */
 429         @SuppressWarnings("unchecked")
 430         private void rehash(HashEntry<K, V> node) {
 431             HashEntry<K, V>[] oldTable = table;
 432             int oldCapacity = oldTable.length;
 433             int newCapacity = oldCapacity << 1;
 434             threshold = (int) (newCapacity * loadFactor);
 435             HashEntry<K, V>[] newTable = new HashEntry[newCapacity];
 436             int sizeMask = newCapacity - 1;
 437             for (int i = 0; i < oldCapacity; i++) {
 438                 HashEntry<K, V> e = oldTable[i];
 439                 if (e != null) {
 440                     HashEntry<K, V> next = e.next;
 441                     int idx = e.hash & sizeMask;
 442                     /* 說明這條鏈上有且僅有一個結點 */
 443                     if (next == null) {
 444                         newTable[idx] = e;
 445                     } else {
 446                         HashEntry<K, V> lastRun = e;
 447                         int lastIdx = idx;
 448                         /*尋找擴容之後,不再原來這條鏈上的最後一個節點lastRun,這個節點之後的所有元素也必定不再原來鏈上,也必須轉移到新的鏈上*/
 449                         for (HashEntry<K, V> last = next; last != null; last = last.next) {
 450                             int k = last.hash & sizeMask;
 451                             if (k != lastIdx) {
 452                                 lastIdx = k;
 453                                 lastRun = last;
 454                             }
 455                         }
 456                         
 457                         /*遍歷完成之後這個lastIdx就是新鏈在HashEntry中的下標*/
 458                         
 459                         /*
 460                          * 重點注意:
 461                          *         1、因為HashEntry[]的擴容是倍增的,始終是2的冪次方,計算某個HashEntry所在HashEntry[]陣列中下標的演演算法為:i = (e.hash >> segmentShift) & segmentMask; 
 462                          *         2、假設擴容之前HashEntry[]的長度為2的k次方,要確定某個hashEntry在HashEntry[]中的下標m,按照上面演演算法,m只與hash值的後k位有關;
 463                          *         3、擴容之後HashEntry[]的長度變為了2的k+1次方,又因為hash、segmentShift、SegmentMask均為final,所以計算的新下標n只與hash值的後k+1位有關;
 464                          *      4、第2步和第3步的的後k位和後k+1位,差異只在第k+1位,這位要麼為0,要麼為1,所以擴容前後,節點的所在陣列中的下標有如下關係:m == n 或者 m+(k<<1) = n;
 465                          *      5、根據第4步得出的結論,擴容之前每一條鏈上的HashEntry節點擴容之後只可能有兩種分佈情況:a、還分佈在原來的下標為m鏈上;b、分佈在新的m+(k<<1)這條鏈上,k不等於0;
 466                          */
 467                         
 468                         /*根據最上面第5步得出的結論,擴容之前不同的鏈上的元素擴容之後是不可能分佈在同一條鏈上的,所以就有如下賦值操作 ,將lastRun之後的所有元素賦值到新的鏈上,也有可能舊鏈*/
 469                         newTable[lastIdx] = lastRun;
 470                         /* 將lastRun之前的節點採用頭插法插入到連結串列的頭部 */
 471                         for (HashEntry<K, V> p = e; p != lastRun; p = p.next) {
 472                             V v = p.value;
 473                             int h = p.hash;
 474                             int k = h & sizeMask;
 475                             HashEntry<K, V> n = newTable[k];
 476                             newTable[k] = new HashEntry<K, V>(h, p.key, v, n);
 477                         }
 478                     }
 479                 }
 480             }
 481             /* 重置這條鏈的頭結點 */
 482             int nodeIndex = node.hash & sizeMask;
 483             node.setNext(newTable[nodeIndex]);
 484             newTable[nodeIndex] = node;
 485             table = newTable;
 486         }
 487 
 488         /**
 489          * Scans for a node containing given key while trying to acquire lock, creating
 490          * and returning one if not found. Upon return, guarantees that lock is held.
 491          * UNlike in most methods, calls to method equals are not screened: Since
 492          * traversal speed doesn't matter, we might as well help warm up the associated
 493          * code and accesses as well.
 494          *
 495          * @return a new node if key not found, else null
 496          */
 497         private HashEntry<K, V> scanAndLockForPut(K key, int hash, V value) {
 498             /* 自旋的過程中嘗試獲取這個節點 */
 499             HashEntry<K, V> first = entryForHash(this, hash);
 500             HashEntry<K, V> e = first;
 501             HashEntry<K, V> node = null;
 502             int retries = -1;
 503             while (!tryLock()) {
 504                 HashEntry<K, V> f;
 505                 if (retries < 0) {
 506                     if (e == null) {
 507                         /* 在自旋嘗試的過程中,當前這條hashEntry鏈遍歷完成了,但是沒有找到這個節點就新建一個結點 */
 508                         if (node == null) {
 509                             node = new HashEntry<K, V>(hash, key, value, null);
 510                             retries = 0;
 511                         }
 512                     } else if (key.equals(e.key)) {
 513                         retries = 0;
 514                     } else {
 515                         e = e.next;
 516                     }
 517                 } else if (++retries > RETRIES_BEFORE_LOCK) {
 518                     /* 自旋達到了最大次數,則不再自旋獲取,阻塞等待 */
 519                     lock();
 520                     break;
 521                 } else if (((retries & 1) == 0) && (f = entryForHash(this, hash)) != first) {
 522                     /* 自旋的過程中,頭結點發生了變化,說明發生了並行的寫操作,重新嘗試 */
 523                     e = first = f;
 524                     retries = -1;
 525                 }
 526             }
 527 
 528             /* 第一次嘗試就獲取到了鎖,或者這條鏈還沒遍歷完就獲取到了鎖則node為空 */
 529             return node;
 530         }
 531 
 532         /**
 533          * Scans for a node containing the given key while trying to acquire lock for a
 534          * remove or replace operation. Upon return, guarantees that lock is held. Note
 535          * that we must lock even if the key is not found, to ensure sequential
 536          * consistency of updates.
 537          */
 538         private void scanAndLock(Object key, int hash) {
 539             // similar to but simpler than scanAndLockForPut
 540             HashEntry<K, V> first = entryForHash(this, hash);
 541             HashEntry<K, V> e = first;
 542             int retries = -1;
 543             /* 自旋的時候做一些遍歷操作,降低cpu的使用率 */
 544             while (!tryLock()) {
 545                 HashEntry<K, V> f;
 546                 if (retries < 0) {
 547                     if (e == null || key.equals(e.key)) {
 548                         retries = 0;
 549                     }
 550                     e = e.next;
 551                 } else if (++retries > MAX_SCAN_RETRIES) {
 552                     lock();
 553                     break;
 554                 } else if (((retries & 1) == 0) && ((f = entryForHash(this, hash)) != first)) {
 555                     /* 嘗試獲取鎖的過程中 */
 556                     e = first = f;
 557                     retries = -1;
 558                 }
 559             }
 560         }
 561 
 562         /**
 563          * Remove; match on key only if value null, else match both.
 564          */
 565         final V remove(Object key, int hash, Object value) {
 566             V oldValue = null;
 567             if (!tryLock()) {
 568                 scanAndLock(key, hash);
 569             }
 570             try {
 571                 HashEntry<K, V>[] tab = table;
 572                 int index = (tab.length - 1) & hash;
 573                 /* current node */
 574                 HashEntry<K, V> e = entryAt(tab, index);
 575                 /* previous node before current node */
 576                 HashEntry<K, V> prev = null;
 577                 while (e != null) {
 578                     K k;
 579                     HashEntry<K, V> next = e.next;
 580                     if ((k = e.key) == key || ((e.hash == hash) && k.equals(key))) {
 581                         V v = e.value;
 582                         /* Value為null的時候只匹配key,否則key和value都需要匹配 */
 583                         if (value == null || value == v || value.equals(value)) {
 584                             if (prev == null) {
 585                                 setEntryAt(tab, index, next);
 586                             } else {
 587                                 prev.setNext(next);
 588                             }
 589                             modCount++;
 590                             count--;
 591                             oldValue = v;
 592                         }
 593                         break;
 594                     }
 595                     prev = e;
 596                     e = next;
 597                 }
 598             } finally {
 599                 unlock();
 600             }
 601             return oldValue;
 602         }
 603 
 604         final boolean replace(K key, int hash, V oldValue, V newValue) {
 605             boolean repalced = false;
 606             if (!tryLock()) {
 607                 /* 獲取鎖失敗,進行一定次數的自旋獲取,還未成功則阻塞獲取 */
 608                 scanAndLock(key, hash);
 609             }
 610 
 611             try {
 612                 for (HashEntry<K, V> e = entryForHash(this, hash); e != null; e = e.next) {
 613                     K k;
 614                     if ((k = e.key) == key || (e.hash == hash && key.equals(k))) {
 615                         /* key相等,並且oldValue值等於原來位置的值才進行替換操作 */
 616                         if (oldValue.equals(e.value)) {
 617                             e.value = newValue;
 618                             ++modCount;
 619                             repalced = true;
 620                         }
 621                         break;
 622                     }
 623                 }
 624             } finally {
 625                 unlock();
 626             }
 627             return repalced;
 628         }
 629 
 630         final V replace(K key, int hash, V value) {
 631             V oldValue = null;
 632             if (!tryLock()) {
 633                 scanAndLock(key, hash);
 634             }
 635 
 636             try {
 637                 HashEntry<K, V> e;
 638                 for (e = entryForHash(this, hash); e != null; e = e.next) {
 639                     K k;
 640                     if ((k = e.key) == key || (e.hash == hash && key.equals(k))) {
 641                         oldValue = e.value;
 642                         e.value = value;
 643                         ++modCount;
 644                         break;
 645                     }
 646                 }
 647             } finally {
 648                 unlock();
 649             }
 650             return oldValue;
 651         }
 652 
 653         final void clear() {
 654             lock();
 655             try {
 656                 HashEntry<K, V>[] tab = table;
 657                 for (int i = 0; i < tab.length; i++)
 658                     setEntryAt(tab, i, null);
 659                 ++modCount;
 660                 count = 0;
 661             } finally {
 662                 unlock();
 663             }
 664         }
 665     }
 666 
 667     // Accessing segments
 668 
 669     /**
 670      * Gets the jth element of given segment array (if nonnull) with volatile
 671      * element access semantics via Unsafe. (The null check can trigger harmlessly
 672      * only during deserialization.) Note: because each element of segments array is
 673      * set only once (using fully ordered writes), some performance-sensitive
 674      * methods rely on this method only as a recheck upon null reads.
 675      */
 676     @SuppressWarnings("unchecked")
 677     static final <K, V> Segment<K, V> segmentAt(Segment<K, V>[] ss, int j) {
 678         long u = (j << SSHIFT) + SBASE;
 679         return ss == null ? null : (Segment<K, V>) UNSAFE.getObjectVolatile(ss, u);
 680     }
 681 
 682     /**
 683      * Returns the segment for the given index, creating it and recording in segment
 684      * table (via CAS) if not already present.
 685      *
 686      * @param k the index
 687      * @return the segment
 688      */
 689     @SuppressWarnings("unchecked")
 690     private Segment<K, V> ensureSegment(int k) {
 691         /* 給當前位置建立一個新的segment */
 692         Segment<K, V>[] ss = this.segments;
 693         long u = (k << SSHIFT) + SBASE;
 694         Segment<K, V> seg;
 695         if ((seg = (Segment<K, V>) UNSAFE.getObjectVolatile(ss, u)) == null) {
 696             /* 以segment[0]作為原型來初始化當前位置的segment */
 697             Segment<K, V> proto = ss[0];
 698             int len = proto.table.length;
 699             float lf = proto.loadFactor;
 700             int threshold = (int) (len * lf);
 701             HashEntry<K, V>[] tab = new HashEntry[len];
 702             if ((seg = (Segment<K, V>) UNSAFE.getObjectVolatile(ss, u)) == null) {
 703                 Segment<K, V> segment = new Segment<>(lf, threshold, tab);
 704                 while ((seg = (Segment<K, V>) UNSAFE.getObjectVolatile(ss, u)) == null) {
 705                     if (UNSAFE.compareAndSwapObject(ss, u, null, seg = segment)) {
 706                         break;
 707                     }
 708                 }
 709             }
 710         }
 711         return seg;
 712     }
 713 
 714     // Hash-based segment and entry accesses
 715 
 716     /**
 717      * Get the segment for the given hash
 718      */
 719     @SuppressWarnings("unchecked")
 720     private Segment<K, V> segmentForHash(int h) {
 721         long u = (((h >>> segmentShift) & segmentMask) << SSHIFT) + SBASE;
 722         return (Segment<K, V>) UNSAFE.getObjectVolatile(segments, u);
 723     }
 724 
 725     /**
 726      * Gets the table entry for the given segment and hash
 727      */
 728     @SuppressWarnings("unchecked")
 729     static final <K, V> HashEntry<K, V> entryForHash(Segment<K, V> seg, int h) {
 730         /* 根據hash值獲取當前segment中,維護的HashEntry陣列中的某一條鏈的頭結點 */
 731         HashEntry<K, V>[] tab;
 732         return (HashEntry<K, V>) ((seg == null || (tab = seg.table) == null) ? null
 733                 : UNSAFE.getObjectVolatile(seg, (((tab.length - 1) & h) << TSHIFT) + TBASE));
 734     }
 735 
 736     /* ---------------- Public operations -------------- */
 737 
 738     /**
 739      * Creates a new, empty map with the specified initial capacity, load factor and
 740      * concurrency level.
 741      *
 742      * @param initialCapacity  the initial capacity. The implementation performs
 743      *                         internal sizing to accommodate this many elements.
 744      * @param loadFactor       the load factor threshold, used to control resizing.
 745      *                         Resizing may be performed when the average number of
 746      *                         elements per bin exceeds this threshold.
 747      * @param concurrencyLevel the estimated number of concurrently updating
 748      *                         threads. The implementation performs internal sizing
 749      *                         to try to accommodate this many threads.
 750      * @throws IllegalArgumentException if the initial capacity is negative or the
 751      *                                  load factor or concurrencyLevel are
 752      *                                  nonpositive.
 753      */
 754     @SuppressWarnings("unchecked")
 755     public ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel) {
 756         if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0)
 757             throw new IllegalArgumentException();
 758         if (concurrencyLevel > MAX_SEGMENTS)
 759             concurrencyLevel = MAX_SEGMENTS;
 760         // Find power-of-two sizes best matching arguments
 761         int sshift = 0;
 762         int ssize = 1;
 763         while (ssize < concurrencyLevel) {
 764             ++sshift;
 765             ssize <<= 1;
 766         }
 767         this.segmentShift = 32 - sshift;
 768         this.segmentMask = ssize - 1;
 769         if (initialCapacity > MAXIMUM_CAPACITY)
 770             initialCapacity = MAXIMUM_CAPACITY;
 771         int c = initialCapacity / ssize;
 772         if (c * ssize < initialCapacity)
 773             ++c;
 774         int cap = MIN_SEGMENT_TABLE_CAPACITY;
 775         while (cap < c)
 776             cap <<= 1;
 777         // create segments and segments[0]
 778         Segment<K, V> s0 = new Segment<K, V>(loadFactor, (int) (cap * loadFactor),
 779                 (HashEntry<K, V>[]) new HashEntry[cap]);
 780         Segment<K, V>[] ss = (Segment<K, V>[]) new Segment[ssize];
 781         UNSAFE.putOrderedObject(ss, SBASE, s0); // ordered write of segments[0]
 782         this.segments = ss;
 783     }
 784 
 785     /**
 786      * Creates a new, empty map with the specified initial capacity and load factor
 787      * and with the default concurrencyLevel (16).
 788      *
 789      * @param initialCapacity The implementation performs internal sizing to
 790      *                        accommodate this many elements.
 791      * @param loadFactor      the load factor threshold, used to control resizing.
 792      *                        Resizing may be performed when the average number of
 793      *                        elements per bin exceeds this threshold.
 794      * @throws IllegalArgumentException if the initial capacity of elements is
 795      *                                  negative or the load factor is nonpositive
 796      *
 797      * @since 1.6
 798      */
 799     public ConcurrentHashMap(int initialCapacity, float loadFactor) {
 800         this(initialCapacity, loadFactor, DEFAULT_CONCURRENCY_LEVEL);
 801     }
 802 
 803     /**
 804      * Creates a new, empty map with the specified initial capacity, and with
 805      * default load factor (0.75) and concurrencyLevel (16).
 806      *
 807      * @param initialCapacity the initial capacity. The implementation performs
 808      *                        internal sizing to accommodate this many elements.
 809      * @throws IllegalArgumentException if the initial capacity of elements is
 810      *                                  negative.
 811      */
 812     public ConcurrentHashMap(int initialCapacity) {
 813         this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
 814     }
 815 
 816     /**
 817      * Creates a new, empty map with a default initial capacity (16), load factor
 818      * (0.75) and concurrencyLevel (16).
 819      */
 820     public ConcurrentHashMap() {
 821         this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
 822     }
 823 
 824     /**
 825      * Creates a new map with the same mappings as the given map. The map is created
 826      * with a capacity of 1.5 times the number of mappings in the given map or 16
 827      * (whichever is greater), and a default load factor (0.75) and concurrencyLevel
 828      * (16).
 829      *
 830      * @param m the map
 831      */
 832     public ConcurrentHashMap(Map<? extends K, ? extends V> m) {
 833         this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1, DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR,
 834                 DEFAULT_CONCURRENCY_LEVEL);
 835         putAll(m);
 836     }
 837 
 838     /**
 839      * Returns <tt>true</tt> if this map contains no key-value mappings.
 840      *
 841      * @return <tt>true</tt> if this map contains no key-value mappings
 842      */
 843     public boolean isEmpty() {
 844         /*
 845          * Sum per-segment modCounts to avoid mis-reporting when elements are
 846          * concurrently added and removed in one segment while checking another, in
 847          * which case the table was never actually empty at any point. (The sum ensures
 848          * accuracy up through at least 1<<31 per-segment modifications before recheck.)
 849          * Methods size() and containsValue() use similar constructions for stability
 850          * checks.
 851          */
 852         /*
 853          * 總體思路是遍歷兩次segment[]陣列,不加鎖操作 第一次遍歷,
 854          * 在遍歷的過程中有任何一個segment中元素數量不為空,就立即返回false,否則就累加每個segment中寫操作的次數modCount;
 855          * 第一次遍歷結束,如果累加的寫操作的次數為0,直接返回true,說明segment[]陣列中沒有任何元素,否則再進行第二次遍歷,任何一個segment不為空
 856          * ,則返回false, 否則就進行第一次計算的累計寫操作次數sum的減法操作,直到遍歷完所有的segment,遍歷結束之後,sum不等於0就說明,
 857          * 在這兩次遍歷的過程中發生了一次寫操作,所以必定不為空。
 858          */
 859         long sum = 0L;
 860         final Segment<K, V>[] segments = this.segments;
 861         for (int i = 0; i < segments.length; i++) {
 862             Segment<K, V> seg = segmentAt(segments, i);
 863             if (seg != null) {
 864                 if (seg.count != 0) {
 865                     return false;
 866                 }
 867                 sum += seg.modCount;
 868             }
 869         }
 870 
 871         if (sum != 0L) {
 872             for (int i = 0; i < segments.length; i++) {
 873                 Segment<K, V> seg = segmentAt(segments, i);
 874                 if (seg != null) {
 875                     if (seg.count != 0) {
 876                         return false;
 877                     }
 878                     sum -= seg.modCount;
 879                 }
 880             }
 881 
 882             if (sum != 0) {
 883                 return false;
 884             }
 885         }
 886         return true;
 887     }
 888 
 889     /**
 890      * Returns the number of key-value mappings in this map. If the map contains
 891      * more than <tt>Integer.MAX_VALUE</tt> elements, returns
 892      * <tt>Integer.MAX_VALUE</tt>.
 893      *
 894      * @return the number of key-value mappings in this map
 895      */
 896     public int size() {
 897         /* 統計size的過程中可以不同的segment中有並行的寫操作,所以只能相對的統計某一個時間範圍內的size大小 */
 898         final Segment<K, V>[] segments = this.segments;
 899         int size;// 計算的大小
 900         long sum;// 本輪計算的累計並行次數
 901         long last = 0L;// 上一次計算的累計並行次數
 902         int retries = -1;// 初始重試次數
 903         boolean overflow;// size是否溢位
 904         try {
 905             /*
 906              * 總體思路:不加鎖先嚐試計算size,最大重試3次,要是在這個最大重試次數的範圍內,segment[]中沒有發生並行寫操作,則結束,
 907              * 否則對所有的segment進行加鎖再統計size
 908              */
 909             for (;;) {
 910                 /* 重試次數達到了閾值,則對所有的段進行加鎖計算 */
 911                 if (retries++ == RETRIES_BEFORE_LOCK) {
 912                     for (int i = 0; i < segments.length; i++) {
 913                         segmentAt(segments, i).lock();
 914                     }
 915                 }
 916 
 917                 sum = 0L;
 918                 size = 0;
 919                 overflow = false;
 920                 for (int i = 0; i < segments.length; i++) {
 921                     Segment<K, V> seg = segmentAt(segments, i);
 922                     if (seg != null) {
 923                         sum += seg.modCount;
 924                         int c = seg.count;
 925                         /* 發生了長度溢位 */
 926                         if (c < 0 || (size += c) < 0) {
 927                             overflow = true;
 928                         }
 929                     }
 930                 }
 931 
 932                 /* 兩次並行修改的次數一樣說明這段時間的size是穩定的,則統計size結束,否則繼續重試,達到閾值,仍不穩定,則對所有segment加鎖,然後再計算 */
 933                 if (sum == last) {
 934                     break;
 935                 }
 936                 last = sum;
 937             }
 938         } finally {
 939             if (retries > RETRIES_BEFORE_LOCK) {
 940                 for (int i = 0; i < segments.length; i++) {
 941                     segmentAt(segments, i).unlock();
 942                 }
 943             }
 944         }
 945         return overflow ? Integer.MAX_VALUE : size;
 946     }
 947 
 948     /**
 949      * Returns the value to which the specified key is mapped, or {@code null} if
 950      * this map contains no mapping for the key.
 951      *
 952      * <p>
 953      * More formally, if this map contains a mapping from a key {@code k} to a value
 954      * {@code v} such that {@code key.equals(k)}, then this method returns
 955      * {@code v}; otherwise it returns {@code null}. (There can be at most one such
 956      * mapping.)
 957      *
 958      * @throws NullPointerException if the specified key is null
 959      */
 960     @SuppressWarnings("unchecked")
 961     public V get(Object key) {
 962         Segment<K, V> seg;
 963         HashEntry<K, V>[] tab;
 964         int h = hash(key);
 965         /* 根據key定位到其所在的segment[]陣列中下標,在記憶體中所對應的地址 */
 966         long u = (((h >>> segmentShift) & segmentMask) << SSHIFT) + SBASE;
 967         if ((seg = (Segment<K, V>) UNSAFE.getObjectVolatile(segments, u)) != null && (tab = seg.table) != null) {
 968             for (HashEntry<K, V> e = (HashEntry<K, V>) UNSAFE.getObjectVolatile(seg,
 969                     (((tab.length - 1) & h) << TSHIFT) + TBASE); e != null; e = e.next) {
 970                 K k;
 971                 if ((k = e.key) == key || (e.hash == h && key.equals(k))) {
 972                     return e.value;
 973                 }
 974             }
 975         }
 976         return null;
 977     }
 978 
 979     /**
 980      * Tests if the specified object is a key in this table.
 981      *
 982      * @param key possible key
 983      * @return <tt>true</tt> if and only if the specified object is a key in this
 984      *         table, as determined by the <tt>equals</tt> method; <tt>false</tt>
 985      *         otherwise.
 986      * @throws NullPointerException if the specified key is null
 987      */
 988     @SuppressWarnings("unchecked")
 989     public boolean containsKey(Object key) {
 990         Segment<K, V> seg;
 991         HashEntry<K, V>[] tab;
 992         int h = hash(key);
 993         long u = (((h >> segmentShift) & segmentMask) << SSHIFT) + SBASE;
 994         if ((seg = (Segment<K, V>) UNSAFE.getObjectVolatile(segments, u)) != null && (tab = seg.table) != null) {
 995             long ut = (((tab.length - 1) & h) << TSHIFT) + TBASE;
 996             for (HashEntry<K, V> e = (HashEntry<K, V>) UNSAFE.getObjectVolatile(tab, ut); e != null; e = e.next) {
 997                 K k;
 998                 if ((k = e.key) == key || (e.hash == h && key.equals(k))) {
 999                     return true;
1000                 }
1001             }
1002         }
1003 
1004         return false;
1005     }
1006 
1007     /**
1008      * Returns <tt>true</tt> if this map maps one or more keys to the specified
1009      * value. Note: This method requires a full internal traversal of the hash
1010      * table, and so is much slower than method <tt>containsKey</tt>.
1011      *
1012      * @param value value whose presence in this map is to be tested
1013      * @return <tt>true</tt> if this map maps one or more keys to the specified
1014      *         value
1015      * @throws NullPointerException if the specified value is null
1016      */
1017     public boolean containsValue(Object value) {
1018         /* 總體和計算size方法思路一致,參見size註釋 */
1019         if (value == null) {
1020             throw new NullPointerException();
1021         }
1022 
1023         final Segment<K, V>[] segments = this.segments;
1024         boolean found = false;
1025         long last = 0;
1026         int retries = -1;
1027         try {
1028             /* 找到了直接跳出到這裡 */
1029             outer: for (;;) {
1030                 if (retries++ == RETRIES_BEFORE_LOCK) {
1031                     for (int i = 0; i < segments.length; i++) {
1032                         segmentAt(segments, i).lock();
1033                     }
1034                 }
1035 
1036                 /* 用來統計並行的操作次數 */
1037                 long sum = 0L;
1038                 for (int i = 0; i < segments.length; i++) {
1039                     Segment<K, V> seg = segmentAt(segments, i);
1040                     HashEntry<K, V>[] tab;
1041                     if (seg != null && (tab = seg.table) != null) {
1042                         for (int j = 0; j < tab.length; j++) {
1043                             HashEntry<K, V> e;
1044                             for (e = entryAt(tab, j); e != null; e = e.next) {
1045                                 V v = e.value;
1046                                 if (v != null && value.equals(v)) {
1047                                     found = true;
1048                                     /* 找到了匹配的value,則跳出到最外層的迴圈 */
1049                                     break outer;
1050                                 }
1051                             }
1052                         }
1053                     }
1054                     sum += seg.modCount;
1055                 }
1056 
1057                 if (retries > 0 && sum == last) {
1058                     break;
1059                 }
1060                 last = sum;
1061             }
1062         } finally {
1063             if (retries > RETRIES_BEFORE_LOCK) {
1064                 for (int i = 0; i < segments.length; i++) {
1065                     segmentAt(segments, i).unlock();
1066                 }
1067             }
1068         }
1069         return found;
1070     }
1071 
1072     /**
1073      * Legacy method testing if some key maps into the specified value in this
1074      * table. This method is identical in functionality to {@link #containsValue},
1075      * and exists solely to ensure full compatibility with class
1076      * {@link java.util.Hashtable}, which supported this method prior to
1077      * introduction of the Java Collections framework.
1078      * 
1079      * @param value a value to search for
1080      * @return <tt>true</tt> if and only if some key maps to the <tt>value</tt>
1081      *         argument in this table as determined by the <tt>equals</tt> method;
1082      *         <tt>false</tt> otherwise
1083      * @throws NullPointerException if the specified value is null
1084      */
1085     public boolean contains(Object value) {
1086         return containsValue(value);
1087     }
1088 
1089     /**
1090      * Maps the specified key to the specified value in this table. Neither the key
1091      * nor the value can be null.
1092      *
1093      * <p>
1094      * The value can be retrieved by calling the <tt>get</tt> method with a key that
1095      * is equal to the original key.
1096      *
1097      * @param key   key with which the specified value is to be associated
1098      * @param value value to be associated with the specified key
1099      * @return the previous value associated with <tt>key</tt>, or <tt>null</tt> if
1100      *         there was no mapping for <tt>key</tt>
1101      * @throws NullPointerException if the specified key or value is null
1102      */
1103     @SuppressWarnings("unchecked")
1104     public V put(K key, V value) {
1105         Segment<K, V> s;
1106         if (value == null) {
1107             throw new NullPointerException();
1108         }
1109         int hash = hash(key);
1110         int j = (hash >>> segmentShift) & segmentMask;
1111         /* 如果當前的segment為空,則建立一個 */
1112         if ((s = (Segment<K, V>) UNSAFE.getObject(segments, (j << SSHIFT) + SBASE)) == null) {
1113             s = ensureSegment(j);
1114         }
1115         return s.put(key, hash, value, false);
1116     }
1117 
1118     /**
1119      * {@inheritDoc}
1120      *
1121      * @return the previous value associated with the specified key, or
1122      *         <tt>null</tt> if there was no mapping for the key
1123      * @throws NullPointerException if the specified key or value is null
1124      */
1125     @SuppressWarnings("unchecked")
1126     public V putIfAbsent(K key, V value) {
1127         Segment<K, V> s;
1128         if (value == null)
1129             throw new NullPointerException();
1130         int hash = hash(key);
1131         int j = (hash >>> segmentShift) & segmentMask;
1132         if ((s = (Segment<K, V>) UNSAFE.getObject(segments, (j << SSHIFT) + SBASE)) == null)
1133             s = ensureSegment(j);
1134         return s.put(key, hash, value, true);
1135     }
1136 
1137     /**
1138      * Copies all of the mappings from the specified map to this one. These mappings
1139      * replace any mappings that this map had for any of the keys currently in the
1140      * specified map.
1141      *
1142      * @param m mappings to be stored in this map
1143      */
1144     public void putAll(Map<? extends K, ? extends V> m) {
1145         for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
1146             put(e.getKey(), e.getValue());
1147     }
1148 
1149     /**
1150      * Removes the key (and its corresponding value) from this map. This method does
1151      * nothing if the key is not in the map.
1152      *
1153      * @param key the key that needs to be removed
1154      * @return the previous value associated with <tt>key</tt>, or <tt>null</tt> if
1155      *         there was no mapping for <tt>key</tt>
1156      * @throws NullPointerException if the specified key is null
1157      */
1158     public V remove(Object key) {
1159         int hash = hash(key);
1160         Segment<K, V> s = segmentForHash(hash);
1161         return s == null ? null : s.remove(key, hash, null);
1162     }
1163 
1164     /**
1165      * {@inheritDoc}
1166      *
1167      * @throws NullPointerException if the specified key is null
1168      */
1169     public boolean remove(Object key, Object value) {
1170         int hash = hash(key);
1171         Segment<K, V> s;
1172         return value != null && (s = segmentForHash(hash)) != null && s.remove(key, hash, value) != null;
1173     }
1174 
1175     /**
1176      * {@inheritDoc}
1177      *
1178      * @throws NullPointerException if any of the arguments are null
1179      */
1180     public boolean replace(K key, V oldValue, V newValue) {
1181         int hash = hash(key);
1182         if (oldValue == null || newValue == null)
1183             throw new NullPointerException();
1184         Segment<K, V> s = segmentForHash(hash);
1185         return s != null && s.replace(key, hash, oldValue, newValue);
1186     }
1187 
1188     /**
1189      * {@inheritDoc}
1190      *
1191      * @return the previous value associated with the specified key, or
1192      *         <tt>null</tt> if there was no mapping for the key
1193      * @throws NullPointerException if the specified key or value is null
1194      */
1195     public V replace(K key, V value) {
1196         int hash = hash(key);
1197         if (value == null) {
1198             throw new NullPointerException();
1199         }
1200         Segment<K, V> seg = segmentForHash(hash);
1201         return seg == null ? null : seg.replace(key, hash, value);
1202     }
1203 
1204     /**
1205      * Removes all of the mappings from this map.
1206      */
1207     public void clear() {
1208         final Segment<K, V>[] segments = this.segments;
1209         for (int j = 0; j < segments.length; ++j) {
1210             Segment<K, V> s = segmentAt(segments, j);
1211             if (s != null)
1212                 s.clear();
1213         }
1214     }
1215 
1216     /**
1217      * Returns a {@link Set} view of the keys contained in this map. The set is
1218      * backed by the map, so changes to the map are reflected in the set, and
1219      * vice-versa. The set supports element removal, which removes the corresponding
1220      * mapping from this map, via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
1221      * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations. It
1222      * does not support the <tt>add</tt> or <tt>addAll</tt> operations.
1223      *
1224      * <p>
1225      * The view's <tt>iterator</tt> is a "weakly consistent" iterator that will
1226      * never throw {@link ConcurrentModificationException}, and guarantees to
1227      * traverse elements as they existed upon construction of the iterator, and may
1228      * (but is not guaranteed to) reflect any modifications subsequent to
1229      * construction.
1230      */
1231     public Set<K> keySet() {
1232         Set<K> ks = keySet;
1233         return (ks != null) ? ks : (keySet = new KeySet());
1234     }
1235 
1236     /**
1237      * Returns a {@link Collection} view of the values contained in this map. The
1238      * collection is backed by the map, so changes to the map are reflected in the
1239      * collection, and vice-versa. The collection supports element removal, which
1240      * removes the corresponding mapping from this map, via the
1241      * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>, <tt>removeAll</tt>,
1242      * <tt>retainAll</tt>, and <tt>clear</tt> operations. It does not support the
1243      * <tt>add</tt> or <tt>addAll</tt> operations.
1244      *
1245      * <p>
1246      * The view's <tt>iterator</tt> is a "weakly consistent" iterator that will
1247      * never throw {@link ConcurrentModificationException}, and guarantees to
1248      * traverse elements as they existed upon construction of the iterator, and may
1249      * (but is not guaranteed to) reflect any modifications subsequent to
1250      * construction.
1251      */
1252     public Collection<V> values() {
1253         Collection<V> vs = values;
1254         return (vs != null) ? vs : (values = new Values());
1255     }
1256 
1257     /**
1258      * Returns a {@link Set} view of the mappings contained in this map. The set is
1259      * backed by the map, so changes to the map are reflected in the set, and
1260      * vice-versa. The set supports element removal, which removes the corresponding
1261      * mapping from the map, via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
1262      * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations. It
1263      * does not support the <tt>add</tt> or <tt>addAll</tt> operations.
1264      *
1265      * <p>
1266      * The view's <tt>iterator</tt> is a "weakly consistent" iterator that will
1267      * never throw {@link ConcurrentModificationException}, and guarantees to
1268      * traverse elements as they existed upon construction of the iterator, and may
1269      * (but is not guaranteed to) reflect any modifications subsequent to
1270      * construction.
1271      */
1272     public Set<Map.Entry<K, V>> entrySet() {
1273         Set<Map.Entry<K, V>> es = entrySet;
1274         return (es != null) ? es : (entrySet = new EntrySet());
1275     }
1276 
1277     /**
1278      * Returns an enumeration of the keys in this table.
1279      *
1280      * @return an enumeration of the keys in this table
1281      * @see #keySet()
1282      */
1283     public Enumeration<K> keys() {
1284         return new KeyIterator();
1285     }
1286 
1287     /**
1288      * Returns an enumeration of the values in this table.
1289      *
1290      * @return an enumeration of the values in this table
1291      * @see #values()
1292      */
1293     public Enumeration<V> elements() {
1294         return new ValueIterator();
1295     }
1296 
1297     /* ---------------- Iterator Support -------------- */
1298 
1299     abstract class HashIterator {
1300         int nextSegmentIndex;
1301         int nextTableIndex;
1302         HashEntry<K, V>[] currentTable;
1303         HashEntry<K, V> nextEntry;
1304         HashEntry<K, V> lastReturned;
1305 
1306         HashIterator() {
1307             nextSegmentIndex = segments.length - 1;
1308             nextTableIndex = -1;
1309             advance();
1310         }
1311 
1312         /**
1313          * Set nextEntry to first node of next non-empty table (in backwards order, to
1314          * simplify checks).
1315          */
1316         final void advance() {
1317             for (;;) {
1318                 if (nextTableIndex >= 0) {
1319                     if ((nextEntry = entryAt(currentTable, nextTableIndex--)) != null)
1320                         break;
1321                 } else if (nextSegmentIndex >= 0) {
1322                     Segment<K, V> seg = segmentAt(segments, nextSegmentIndex--);
1323                     if (seg != null && (currentTable = seg.table) != null)
1324                         nextTableIndex = currentTable.length - 1;
1325                 } else
1326                     break;
1327             }
1328         }
1329 
1330         final HashEntry<K, V> nextEntry() {
1331             HashEntry<K, V> e = nextEntry;
1332             if (e == null)
1333                 throw new NoSuchElementException();
1334             lastReturned = e; // cannot assign until after null check
1335             if ((nextEntry = e.next) == null)
1336                 advance();
1337             return e;
1338         }
1339 
1340         public final boolean hasNext() {
1341             return nextEntry != null;
1342         }
1343 
1344         public final boolean hasMoreElements() {
1345             return nextEntry != null;
1346         }
1347 
1348         public final void remove() {
1349             if (lastReturned == null)
1350                 throw new IllegalStateException();
1351             ConcurrentHashMap.this.remove(lastReturned.key);
1352             lastReturned = null;
1353         }
1354     }
1355 
1356     final class KeyIterator extends HashIterator implements Iterator<K>, Enumeration<K> {
1357         public final K next() {
1358             return super.nextEntry().key;
1359         }
1360 
1361         public final K nextElement() {
1362             return super.nextEntry().key;
1363         }
1364     }
1365 
1366     final class ValueIterator extends HashIterator implements Iterator<V>, Enumeration<V> {
1367         public final V next() {
1368             return super.nextEntry().value;
1369         }
1370 
1371         public final V nextElement() {
1372             return super.nextEntry().value;
1373         }
1374     }
1375 
1376     /**
1377      * Custom Entry class used by EntryIterator.next(), that relays setValue changes
1378      * to the underlying map.
1379      */
1380     final class WriteThroughEntry extends AbstractMap.SimpleEntry<K, V> {
1381         WriteThroughEntry(K k, V v) {
1382             super(k, v);
1383         }
1384 
1385         /**
1386          * Set our entry's value and write through to the map. The value to return is
1387          * somewhat arbitrary here. Since a WriteThroughEntry does not necessarily track
1388          * asynchronous changes, the most recent "previous" value could be different
1389          * from what we return (or could even have been removed in which case the put
1390          * will re-establish). We do not and cannot guarantee more.
1391          */
1392         public V setValue(V value) {
1393             if (value == null)
1394                 throw new NullPointerException();
1395             V v = super.setValue(value);
1396             ConcurrentHashMap.this.put(getKey(), value);
1397             return v;
1398         }
1399     }
1400 
1401     final class EntryIterator extends HashIterator implements Iterator<Entry<K, V>> {
1402         public Map.Entry<K, V> next() {
1403             HashEntry<K, V> e = super.nextEntry();
1404             return new WriteThroughEntry(e.key, e.value);
1405         }
1406     }
1407 
1408     final class KeySet extends AbstractSet<K> {
1409         public Iterator<K> iterator() {
1410             return new KeyIterator();
1411         }
1412 
1413         public int size() {
1414             return ConcurrentHashMap.this.size();
1415         }
1416 
1417         public boolean isEmpty() {
1418             return ConcurrentHashMap.this.isEmpty();
1419         }
1420 
1421         public boolean contains(Object o) {
1422             return ConcurrentHashMap.this.containsKey(o);
1423         }
1424 
1425         public boolean remove(Object o) {
1426             return ConcurrentHashMap.this.remove(o) != null;
1427         }
1428 
1429         public void clear() {
1430             ConcurrentHashMap.this.clear();
1431         }
1432     }
1433 
1434     final class Values extends AbstractCollection<V> {
1435         public Iterator<V> iterator() {
1436             return new ValueIterator();
1437         }
1438 
1439         public int size() {
1440             return ConcurrentHashMap.this.size();
1441         }
1442 
1443         public boolean isEmpty() {
1444             return ConcurrentHashMap.this.isEmpty();
1445         }
1446 
1447         public boolean contains(Object o) {
1448             return ConcurrentHashMap.this.containsValue(o);
1449         }
1450 
1451         public void clear() {
1452             ConcurrentHashMap.this.clear();
1453         }
1454     }
1455 
1456     final class EntrySet extends AbstractSet<Map.Entry<K, V>> {
1457         public Iterator<Map.Entry<K, V>> iterator() {
1458             return new EntryIterator();
1459         }
1460 
1461         public boolean contains(Object o) {
1462             if (!(o instanceof Map.Entry))
1463                 return false;
1464             Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
1465             V v = ConcurrentHashMap.this.get(e.getKey());
1466             return v != null && v.equals(e.getValue());
1467         }
1468 
1469         public boolean remove(Object o) {
1470             if (!(o instanceof Map.Entry))
1471                 return false;
1472             Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
1473             return ConcurrentHashMap.this.remove(e.getKey(), e.getValue());
1474         }
1475 
1476         public int size() {
1477             return ConcurrentHashMap.this.size();
1478         }
1479 
1480         public boolean isEmpty() {
1481             return ConcurrentHashMap.this.isEmpty();
1482         }
1483 
1484         public void clear() {
1485             ConcurrentHashMap.this.clear();
1486         }
1487     }
1488 
1489     /* ---------------- Serialization Support -------------- */
1490 
1491     /**
1492      * Save the state of the <tt>ConcurrentHashMap</tt> instance to a stream (i.e.,
1493      * serialize it).
1494      * 
1495      * @param s the stream
1496      * @serialData the key (Object) and value (Object) for each key-value mapping,
1497      *             followed by a null pair. The key-value mappings are emitted in no
1498      *             particular order.
1499      */
1500     private void writeObject(java.io.ObjectOutputStream s) throws IOException {
1501         // force all segments for serialization compatibility
1502         for (int k = 0; k < segments.length; ++k)
1503             ensureSegment(k);
1504         s.defaultWriteObject();
1505 
1506         final Segment<K, V>[] segments = this.segments;
1507         for (int k = 0; k < segments.length; ++k) {
1508             Segment<K, V> seg = segmentAt(segments, k);
1509             seg.lock();
1510             try {
1511                 HashEntry<K, V>[] tab = seg.table;
1512                 for (int i = 0; i < tab.length; ++i) {
1513                     HashEntry<K, V> e;
1514                     for (e = entryAt(tab, i); e != null; e = e.next) {
1515                         s.writeObject(e.key);
1516                         s.writeObject(e.value);
1517                     }
1518                 }
1519             } finally {
1520                 seg.unlock();
1521             }
1522         }
1523         s.writeObject(null);
1524         s.writeObject(null);
1525     }
1526 
1527     /**
1528      * Reconstitute the <tt>ConcurrentHashMap</tt> instance from a stream (i.e.,
1529      * deserialize it).
1530      * 
1531      * @param s the stream
1532      */
1533     @SuppressWarnings("unchecked")
1534     private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
1535         s.defaultReadObject();
1536 
1537         // set hashMask
1538         UNSAFE.putIntVolatile(this, HASHSEED_OFFSET, randomHashSeed(this));
1539 
1540         // Re-initialize segments to be minimally sized, and let grow.
1541         int cap = MIN_SEGMENT_TABLE_CAPACITY;
1542         final Segment<K, V>[] segments = this.segments;
1543         for (int k = 0; k < segments.length; ++k) {
1544             Segment<K, V> seg = segments[k];
1545             if (seg != null) {
1546                 seg.threshold = (int) (cap * seg.loadFactor);
1547                 seg.table = (HashEntry<K, V>[]) new HashEntry[cap];
1548             }
1549         }
1550 
1551         // Read the keys and values, and put the mappings in the table
1552         for (;;) {
1553             K key = (K) s.readObject();
1554             V value = (V) s.readObject();
1555             if (key == null)
1556                 break;
1557             put(key, value);
1558         }
1559     }
1560 
1561     // Unsafe mechanics
1562     private static final sun.misc.Unsafe UNSAFE;
1563     private static final long SBASE;
1564     private static final int SSHIFT;
1565     private static final long TBASE;
1566     private static final int TSHIFT;
1567     private static final long HASHSEED_OFFSET;
1568 
1569     static {
1570         int ss, ts;
1571         try {
1572             UNSAFE = sun.misc.Unsafe.getUnsafe();
1573             Class tc = HashEntry[].class;
1574             Class sc = Segment[].class;
1575             /* 獲取陣列中第0個元素在陣列物件中的偏移量 */
1576             TBASE = UNSAFE.arrayBaseOffset(tc);
1577             SBASE = UNSAFE.arrayBaseOffset(sc);
1578             /* 獲取陣列中每個元素的長度大小 */
1579             ts = UNSAFE.arrayIndexScale(tc);
1580             ss = UNSAFE.arrayIndexScale(sc);
1581             HASHSEED_OFFSET = UNSAFE.objectFieldOffset(ConcurrentHashMap.class.getDeclaredField("hashSeed"));
1582         } catch (Exception e) {
1583             throw new Error(e);
1584         }
1585         if ((ss & (ss - 1)) != 0 || (ts & (ts - 1)) != 0)
1586             throw new Error("data type scale not a power of two");
1587         /* 陣列中元素的大小用2的冪次表示,如ss =16,SSHIFT = 4; */
1588         SSHIFT = 31 - Integer.numberOfLeadingZeros(ss);
1589         TSHIFT = 31 - Integer.numberOfLeadingZeros(ts);
1590     }
1591 
1592 }
View Code