Это хождение по тонкому льду, но вот объяснение. Проблема видимости означает, что некоторые потоки могут видеть старую версию, а некоторые - новую. В нашем случае некоторые потоки видят 0
, а другие - cachedHashCode
.
Потоки, которые вызывают hashCode()
и видят cachedHashCode
, просто вернут его (if (h == 0)
условие не выполнено) и все работает.
Но потоки, которые видят 0
(несмотря на то, что cachedHashCode
, возможно, уже были вычислены), просто снова пересчитают его.
Другими словами, в худшем случае каждый поток войдет в ветвь, впервые увидев 0
(например, если бы это было ThreadLocal
).
Так как computeHashCode()
является идемпотентом (очень важно), то как вызов его несколько раз (разными потоками), так и переназначение его одной и той же переменной не должно иметь побочных эффектов.