ConcurrentHashMap.newKeySet()
возвращает:
/**
* Creates a new {@link Set} backed by a ConcurrentHashMap
* from the given type to {@code Boolean.TRUE}.
*
* @param <K> the element type of the returned set
* @return the new set
* @since 1.8
*/
public static <K> KeySetView<K,Boolean> newKeySet() {
return new KeySetView<K,Boolean>
(new ConcurrentHashMap<K,Boolean>(), Boolean.TRUE);
}
, как вы можете видеть, он поддерживается ConcurrentHashMap.Вы можете использовать возвращенный экземпляр без какой-либо синхронизации.
.iterator()
метод возвращает новый KeyIterator
, который поддерживается картой Node<K,V>[] table
, поэтому, если вы выполняете итерацию в одном конкретном потоке, это означает, что вы увидите снимок массива Node
, и каждый узел в правильном состоянии bc Node
имеет изменчивые ссылки внутри, но существует минимальный шанс, что вы увидите новые элементы, добавленные к исходной карте, поскольку точки итератора ссылки не являются изменчивыми.Другими словами, вы просто выполняете итерацию по массиву без какой-либо гарантии, если этот элемент все еще существует в исходной карте atm или там добавлено какое-то новое, но вы можете видеть текущее состояние каждого узла, bc:
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
volatile V val;
volatile Node<K,V> next;
key
является окончательным
val
является изменчивым