hashCode的生成策略是通过全局变量控制的,默认为5,
也可以通过jvm启动参数来进行控制:-XX:hashCode=N
第一种算法:
if (hashCode == 0) {
// This form uses an unguarded global Park-Miller RNG,
// so it's possible for two threads to race and generate the same RNG.
// On MP system we'll have lots of RW access to a global, so the
// mechanism induces lots of coherency traffic.
value = os::random();
}
这种生成算法,使用的一种Park-Miller RNG的随机数生成策略。不过需要注意的是……这个随机算法在高并发的时候会出现自旋等待
第二种算法:
if (hashCode == 1) {
// This variation has the property of being stable (idempotent)
// between STW operations. This can be useful in some of the 1-0
// synchronization schemes.
intptr_t addrBits = intptr_t(obj) >> 3 ;
value = addrBits ^ (addrBits >> 5) ^ GVars.stwRandom ;
}
这个算法,真的是对象的内存地址了,直接获取对象的 intptr_t 类型指针
第三种算法:
if (hashCode == 2) {
value = 1 ; // for sensitivity testing
}
固定返回 1,应该是用于内部的测试场景
第四种算法:
if (hashCode == 3) {
value = ++GVars.hcSequence ;
}
自增嘛,所有对象的 hashCode 都使用这一个自增变量
第五种算法:
if (hashCode == 4) {
value = intptr_t(obj) ;
}
这里和第 2 种算法其实区别不大,都是返回对象地址,只是第 2 种算法是一个变体。
第六种算法:
unsigned t = Self->_hashStateX ;
t ^= (t << 11) ;
Self->_hashStateX = Self->_hashStateY ;
Self->_hashStateY = Self->_hashStateZ ;
Self->_hashStateZ = Self->_hashStateW ;
unsigned v = Self->_hashStateW ;
v = (v ^ (v >> 19)) ^ (t ^ (t >> 8)) ;
Self->_hashStateW = v ;
value = v ;
当前状态值进行异或(XOR)运算得到的一个 hash 值,相比前面的自增算法和随机算法来说效率更高,但重复率应该也会相对增高,不过 hashCode 重复又有什么关系呢……
本来 jvm 就不保证这个值一定不重复,像 HashMap 里的链地址法就是解决 hash 冲突用的.
网友评论