ThreadLocal中魔数0x61c88647如何得到

根据ThreadLocal源码分析(简单)这篇文章,我们得到:
首先,这个魔数得是和Intger.MAX_VALUE互质,那样才能保证累加之后,不会出现遗漏现象。
其次,尽量让没两个数之间距离较远,因为nextIndex的操作是累加,如果靠的太近,就会出现不断循环还是找不到空位的情况,简而言之就是要尽量散列

首先,我们以长度8为例,这时候的魔数最好是几呢?
2、4、6、8排除,与8互质
1、7排除,每次的值都太接近
只剩下3、5了,而3和5本质是一样的3+5=8,对称位。

普遍的思想是斐波那契数列
1、1、2、3、5、8、13、21、34

以长度为13举例,生成的数值为
8、3、11、6、1、9、4、12、7、2、10、5、0循环
很散列了

之所以是斐波那契数列,我的想法是这样的。
我们把所有的数都放置到长度为1的数轴上
第一个点放在0处,第二个点放在x处,第三个点放在2x-1处…
在防止第二个点和第三个点的思想是一样的,尽量散列,所以他们在空位的占位也应该是一样的
第一个点占位比x/1
第二个点占位比(2x-1)/x(剩余的位置是1-x)
两个对称位
x+(2x-1)/x = 1
得:x*x+x-1=0
正数解是(Math.sqrt(5) - 1) / 2,而斐波那契数列的比值无限接近这个数的,我们暂时把这数称之为K
我们来看魔数0x61c88647和K的关系
魔数的十进制为1640531527
1640531527/(2^32) ~= 0.38196601136588;
K ^= 0.6180339887498949
很明显嘛,因为有循环,所以魔数是有对称位的。
当然,这个K其实就是黄金分割数

发布了148 篇原创文章 · 获赞 18 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_33321609/article/details/104481220