Является ли Set of ConcurrentHashMap потокобезопасным в foreach?
Безопасно ли выполнять операции foreach, add, remove, size в разных потоках со следующим набором?
private final Set<MyObject> myConcurrentHashSet = ConcurrentHashMap.newKeySet();
Т.е. мне не нужно получать максимальную точность в операциях foreach или size, но я должен быть уверен, что при выполнении операций foreach / add / remove / size не будет никаких исключений.
Я знаю, что ConcurrentHashMap является потокобезопасным, но я запутался в безопасности потоков своего набора.
2 ответа
Да, представление keySet является потокобезопасным, newKeySet в java >=8 эквивалентно этой форме Java 7:
для Java <= 7
ConcurrentHashMap c = ...;
Set threadSafeSet = c.keySet();
для Java> = 8
Set threadSafeSet = ConcurrentHashMap.newKeySet();
Из документации ConcurrentHashMap:
Операции извлечения (включая get) обычно не блокируются, поэтому могут перекрываться с операциями обновления (включая put и remove). Извлечения отражают результаты самых последних завершенных операций обновления, проводимых с момента их появления. (Более формально, операция обновления для данного ключа имеет отношение "происходит до" с любым (не нулевым) поиском для этого ключа, сообщающего об обновленном значении.)
,,Точно так же,Iterators, Spliterators и Enumerations возвращают элементы, отражающие состояние хеш-таблицы в некоторой точке во время или после создания итератора / перечисления. Они не генерируют ConcurrentModificationException. Однако итераторы предназначены для использования только одним потоком за раз.