探究ConcurrentHashMap中鍵值對在Segment[]的下標如何確定
阿新 • • 發佈:2018-12-14
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 }