关于ConcurrentHashMap构造方法initialCapacity参数及tableSizeFor入参的疑问
initialCapacity + (initialCapacity >>> 1) + 1 Calculation in ConcurrentHashMap's Constructor Great question! Let's break down what this calculation does and why it's there—this is all about ensuring the map can handle your expected number of elements without early resizing, while using efficient bitwise operations.
Core Purpose
First, remember that ConcurrentHashMap uses a default load factor of 0.75. This means the map will resize when the number of elements reaches 75% of its current capacity. When you pass an initialCapacity to the constructor, you're telling the map you want it to hold at least that many elements without triggering a resize.
To fulfill this, the map needs to compute an initial capacity (a power of 2, since ConcurrentHashMap uses power-of-two sized tables) such that:
capacity * 0.75 >= initialCapacity
Rearranged, that means capacity >= initialCapacity / 0.75 (or ~1.333 * initialCapacity). The calculation initialCapacity + (initialCapacity >>> 1) + 1 is an efficient way to get a value that guarantees this condition is met.
Breaking Down the Calculation
Let's unpack each part:
initialCapacity >>> 1: This is an unsigned right shift by 1 bit, which is equivalent to integer division by 2 (e.g., 100 >>> 1 = 50, 128 >>> 1 = 64). Bitwise operations are faster than arithmetic division, so this is a performance optimization that avoids floating-point operations entirely.initialCapacity + (initialCapacity >>> 1): Adding the original value to its half gives us 1.5 times the initialCapacity (e.g., 100 + 50 = 150, 128 + 64 = 192).+ 1: This handles edge cases where 1.5x the initial capacity is exactly a power of two. Adding 1 ensures we don't end up with a capacity that's just barely too small when multiplied by 0.75.
Why This Works
1.5x is greater than the ~1.333x we need to satisfy capacity * 0.75 >= initialCapacity. By passing this larger value to tableSizeFor() (which returns the smallest power of two greater than or equal to its input), we guarantee the resulting capacity will be large enough to hold your expected elements without resizing.
For example:
If you pass
initialCapacity = 100:- Calculation gives
100 + 50 + 1 = 151 tableSizeFor(151)returns 256 (the smallest power of two ≥151)- 256 * 0.75 = 192, which is ≥100—so the map can hold 100 elements without resizing.
- Calculation gives
If you pass
initialCapacity = 128:- Calculation gives
128 + 64 + 1 = 193 tableSizeFor(193)returns 256- 256 * 0.75 = 192 ≥128—again, no early resize.
- Calculation gives
Edge Case Handling
The constructor also checks if initialCapacity is near MAXIMUM_CAPACITY (2^30). If initialCapacity >= MAXIMUM_CAPACITY >>> 1 (2^29), it skips the calculation and sets the capacity directly to MAXIMUM_CAPACITY—this avoids overflow from the 1.5x calculation and ensures we don't exceed the map's maximum allowed size.
内容的提问来源于stack exchange,提问作者Anonemous

