用Java字符串实现hashCode

用Java字符串实现hashCode,java,Java,奇怪的是,在String的hashCode实现中,在hashCode实现(v1.8.065)中创建额外引用的原因是什么: ? 除了将值从堆复制到堆栈以加快速度之外,它还涉及@zapl注释中描述的竞争条件。在他发表评论之前,这对我来说并不明显。似乎意图是将散列和值句柄显式地放在堆栈上重复问题的链接有答案。图纳基标记了正确的dup。他们不需要一个重复读取数据的指令。他们关心的是访问速度稍微慢一点:这不是为了避免getopt。这是一场数据竞赛,因为散列既不是易失性也不是同步的。这就是为什么他们不返回h

奇怪的是,在String的hashCode实现中,在hashCode实现(v1.8.065)中创建额外引用的原因是什么:

?


除了将值从堆复制到堆栈以加快速度之外,它还涉及@zapl注释中描述的竞争条件。在他发表评论之前,这对我来说并不明显。

似乎意图是将
散列
句柄显式地放在堆栈上

重复问题的链接有答案。图纳基标记了正确的dup。他们不需要一个重复读取数据的指令。他们关心的是访问速度稍微慢一点:这不是为了避免getopt。这是一场数据竞赛,因为
散列
既不是
易失性
也不是同步的。这就是为什么他们不
返回hash
(无法保证您读取的值)我不同意这种说法。hash是int(不长),即所有操作都是原子的,在最坏的情况下,您只需计算两次,这可能在两种情况下都会发生。这不是关于原子设置值,而是关于操作(重新)排序。从关于您的版本的链接文章中:我在这里所做的是添加一个额外的读取:在返回之前对哈希进行第二次读取。尽管听起来很奇怪,而且不太可能发生,但第一次读取可以返回正确计算的哈希值,第二次读取可以返回0!这在内存模型下是允许的,因为该模型允许对操作进行广泛的重新排序。第二次读取实际上可以在代码中移动,以便处理器在第一次读取之前执行!杰里米·曼森是JMM的作者之一。我想他知道他在那里写什么:)TBH,我不明白在什么情况下,重新排序读取是合法的,这样在值仍然为0的情况下才会发生。我想这确实避免了重复加载字段。现代JVM不太可能需要这种方法,但这种方法也使用了相当旧的代码。例如,jrockit(从Java7开始就与hotspot合并)当然可以在本地为您缓存字段引用(这只是它所做的最简单的事情之一)。
public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
        char val[] = value;

        for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i];
        }
        hash = h;
    }
    return h;
}
public int hashCode() {
    if (hash == 0 && value.length > 0) {
        int h = 0;
        for (int i = 0; i < value.length; i++) {
            h = 31 * h + value[i];
        }
        hash = h;
    }
    return hash;
}