Я заметил, что ConcurrentHashMap полностью переписан на Java 8, чтобы быть более "незаблокированным". Я просмотрел код метода get()
и вижу, что явного механизма блокировки нет:
public V get(Object key) {
Node<K,V>[] tab; Node<K,V> e, p; int n, eh; K ek;
int h = spread(key.hashCode());
if ((tab = table) != null && (n = tab.length) > 0 &&
(e = tabAt(tab, (n - 1) & h)) != null) {
if ((eh = e.hash) == h) {
if ((ek = e.key) == key || (ek != null && key.equals(ek)))
return e.val;
}
else if (eh < 0)
return (p = e.find(h, key)) != null ? p.val : null;
while ((e = e.next) != null) {
if (e.hash == h &&
((ek = e.key) == key || (ek != null && key.equals(ek))))
return e.val;
}
}
return null;
}
Вопрос:
Как можно видеть из одного потока, изменения, сделанные для этого хэш файла из других потоков, поскольку код не находится под зонтиком синхронизации (который обеспечивал бы выполнение отношения "раньше" )?
Примечание. Вся ConcurrentHashMap является оболочкой таблицы:
transient volatile Node<K,V>[] table;
Итак, table
является изменчивой ссылкой на массив, а не ссылкой на массив летучих элементов! Это означает, что если кто-то обновляет элемент внутри этого массива, модификация не будет отображаться в других потоках.