查看Java的String
类,我们可以看到哈希码在首次评估后被缓存。
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
额外的变量?
答案 0 :(得分:5)
只是因为hash
值在循环中发生了变化,而没有中间临时变量的解决方案不是线程安全的。考虑在多个线程中调用此方法。
说thread-1
开始hash
计算,它不再是0
。稍后片刻thread-2
会在同一个对象上调用相同的方法hashCode()
,并看到hash
不是0
,但thread-1
尚未完成计算。结果,将使用thread-2
错误的hash
(未完全计算)值。
答案 1 :(得分:3)
这是一种简单而廉价的同步机制。
如果线程第一次调用hashCode()并且第二个线程在第一个线程计算哈希时再次调用它,则第二个线程将返回不正确的哈希值(第一个线程中计算的中间值)如果直接使用属性。
答案 2 :(得分:1)
说得很简单:本地原语h
很好本地;因此线程安全;而不是共享的hash
。