ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
table = new Entry[INITIAL_CAPACITY];
int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
table[i] = new Entry(firstKey, firstValue);
size = 1;
setThreshold(INITIAL_CAPACITY);
}
取模(求余)运算
在threadlocal中有一句int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
这里的位运算的实质是去一个取模(求余)运算,决定一个key应该放在数组的哪个index上。
当取模运算中,除数是2的N次方时,既这个数用二进制表示的时候一定只有一个1,比如16,在java的Integer中的2进制实质就是
000000000000000000000000000010000
减一就是
000000000000000000000000000001111
与被除数做与运算,被除数刚好高位就被消除,只剩下低位。既比除数大,但没有超过一倍的部分被保留。这刚好是取模(求余)运算。
之所以这么做,是因为位运算的效率要远高于普通的取模运算。
为什么要用0x61c88647
这个数是Integer有符号整数的0.618倍,既黄金比例,斐波拉契数列。
使用这个比例,可以使key在数组上被更均匀的分散。至于为什么,是一个复杂的数学问题。不懂,不展开讨论。
网友评论