Скажем, у вас есть вектор целых чисел, содержащий 1-10, и вы хотите удалить нечетные числа. Вы перебираете этот список, ища шансы и используя метод Iterators remove()
. После этого у вас есть некоторый код, который, конечно, предполагает, что в векторе нет нечетных чисел. Если другой поток изменяет вектор во время этого процесса, иногда может существовать нечетное число (в зависимости от состояния гонки), что нарушает код, который следует после. Возможно, это даже не сломалось сразу; может быть, это не вызывает проблемы до нескольких часов или дней спустя - очень трудно устранить неисправность. Вот что происходит с методом elements()
.
Под отказоустойчивостью подразумевается попытка обнаружить эту (потенциальную) проблему, как только она возникает, и подача сигнала тревоги, что значительно облегчает поиск и устранение неисправностей. Как только обнаруживается, что другой поток изменил коллекцию, возникает исключение. Вот что происходит с итераторами.
Итераторы, возвращаемые iterator()
и listIterator()
, активно следят за неожиданными изменениями в базовом списке. Класс Vector (фактически его родительский объект AbstractList) увеличивает счетчик каждый раз, когда он изменяется. При создании итераторов для вектора они сохраняют копию счетчика модификаций вектора. Каждый раз, когда вы вызываете next()
или remove()
, итератор сравнивает свое сохраненное значение для счетчика с фактическим счетчиком вектора. Если они различаются, выдается исключение ConcurrentModificationException.