1. 程式人生 > >探究ConcurrentHashMap中鍵值對在Segment[]的下標如何確定

探究ConcurrentHashMap中鍵值對在Segment[]的下標如何確定

1 public ConcurrentHashMap(int initialCapacity, 2 float loadFactor, int concurrencyLevel) { 3 if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0) 4 throw new IllegalArgumentException(); 5 if (concurrencyLevel > MAX_SEGMENTS)
6 concurrencyLevel = MAX_SEGMENTS; 7 int sshift = 0; 8 int ssize = 1; 9 //2^sshif=ssize,例:sshift=4,ssize=16; 10 //根據concurrentLevel計算得出ssize為segments陣列長度 11 while (ssize < concurrencyLevel) { 12 ++sshift; 13 ssize <<= 1;
14 } 15 //segmentShift和segmentMask的定義 16 this.segmentShift = 32 - sshift; 17 this.segmentMask = ssize - 1; 18 if (initialCapacity > MAXIMUM_CAPACITY) 19 initialCapacity = MAXIMUM_CAPACITY; 20 //計算cap的大小,即Segment中HashEntry的陣列長度,cap也一定為2的n次方.
21 int c = initialCapacity / ssize; 22 if (c * ssize < initialCapacity) 23 ++c; 24 int cap = MIN_SEGMENT_TABLE_CAPACITY; 25 while (cap < c) 26 cap <<= 1; 27 //建立segments陣列並初始化第一個Segment,其餘的Segment延遲初始化 28 Segment<K,V> s0 = 29 new Segment<K,V>(loadFactor, (int)(cap * loadFactor), 30 (HashEntry<K,V>[])new HashEntry[cap]); 31 Segment<K,V>[] ss = (Segment<K,V>[])new Segment[ssize]; 32 UNSAFE.putOrderedObject(ss, SBASE, s0); 33 this.segments = ss; 34 }