java 字符串哈希码缓存机制

java String hashcode caching mechanism

查看 Java 的 String class 我们可以看到哈希码在第一次评估后被缓存。

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;
}

其中hash是一个实例变量。我有一个问题,为什么我们需要那个 h 额外变量?

仅仅是因为 hash 值在循环中发生变化,没有中间临时变量的解决方案不是线程安全的。考虑在多个线程中调用此方法。

thread-1 开始了 hash 计算,它不再是 0。片刻之后 thread-2 在同一对象上调用相同的方法 hashCode() 并发现 hash 不是 0,但 thread-1 尚未完成其计算。结果,在 thread-2 中将使用错误的 hash(未完全计算)值。

这是一种简单且廉价的同步机制。

如果一个线程第一次调用 hashCode(),而第二个线程在第一个线程计算哈希值时再次调用它,则第二个线程将 return 一个不正确的哈希值(在第一个线程中计算)如果直接使用属性。

说的很简单:local primitive h 很好 local;因此线程安全;与共享的 hash 相反。