Обратите внимание, что эта реализация не синхронизирована. Если несколько потоки обращаются к карте ha sh одновременно, и по крайней мере один из потоков структурно модифицирует карту, он должен быть синхронизирован извне. (Структурная модификация - это любая операция, которая добавляет или удаляет одно или несколько сопоставлений; простое изменение значения, связанного с ключом, который уже содержится в экземпляре, не является структурной модификацией.) Обычно это выполняется путем синхронизации на некотором объекте, который естественным образом инкапсулирует карту. . Если такого объекта не существует, карту следует «обернуть» с помощью метода Collections.synchronizedMap. Лучше всего это делать во время создания, чтобы предотвратить случайный несинхронизированный доступ к карте:
Map m = Collections.synchronizedMap(new HashMap(...));
Итераторы, возвращаемые всеми «методами представления коллекции» этого класса: безотказно : если карта структурно изменена в любое время после создания итератора, любым способом, кроме как с помощью собственного метода удаления итератора, итератор выдаст ConcurrentModificationException
. Таким образом, перед лицом параллельной модификации итератор выходит из строя быстро и чисто, вместо того, чтобы рисковать произвольным, недетерминированным c поведением в неопределенное время в будущем.
Обратите внимание, что безотказное поведение итератор не может быть гарантирован, поскольку, вообще говоря, невозможно дать какие-либо жесткие гарантии при наличии несинхронизированной параллельной модификации. Отказоустойчивые итераторы выдают ConcurrentModificationException
по принципу максимальных усилий. Следовательно, было бы неправильно писать программу, правильность которой зависела бы от этого исключения: отказоустойчивое поведение итераторов должно использоваться только для обнаружения ошибок.