hashCode 生成策略

2022-01-24  本文已影响0人  小郭子

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 冲突用的.

上一篇 下一篇

猜你喜欢

热点阅读