2015-06-08 1 views
2

У меня есть коды ниже, и я ожидал бы от сценария случая 2 ConcurrentModificationException, но он работает успешно. Как я знаю, что если я сделать то же самое с одним ключом на карте она не бросает исключение, потому что here , но еще раз, когда я воспроизвести этот сценарий, имеющие несколько ключей с двумя случаями -В Карте, если мы делаем модификацию с существующими ключами, мы не получаем ConcurrentModificationException

  1. модификации по новому ключу.
  2. модификация существующий ключ.

Случай 1:

Map<String,String> mp = new HashMap<String,String>(); 
    mp.put("1", "10"); 
    mp.put("2", "11"); 
    mp.put("3", "12"); 
    mp.put("4", "13"); 

    for (String key :mp.keySet()) { 
     mp.put("5", "14"); 
    } 

Это будет работать, как и ожидалось, броски ConcurrentModificationException.

Случай 2:

Map<String,String> mp = new HashMap<String,String>(); 
    mp.put("1", "10"); 
    mp.put("2", "11"); 
    mp.put("3", "12"); 
    mp.put("4", "13"); 

    for (String key :mp.keySet()) { 
     mp.put(key, "14"); 
    } 

Это будет не бросает ConcurrentModificationException. Зачем ??

ответ

4

В первом случае вы , изменяя структуру карты, чтобы получить CME (добавив новую пару ключ/значение). Во втором случае вы не изменяете структуру (значения перезаписи для существующих ключей). поэтому вы не получите CME

1

ConcurrentModificationException выбрасывается, когда его структура изменяется во время итерации по ней, но во втором случае изменений в структуре нет. Это означает, что только обновление для существующего ключа в карте (ни добавлении или удалении во втором случае, который вызвал бы изменение структуры)

См http://javahungry.blogspot.com/2014/04/fail-fast-iterator-vs-fail-safe-iterator-difference-with-example-in-java.html

+1

@TheLostMind исправил его. –

1

Вы можете обратиться to the javadoc:

Итераторов [...] являются неустойчивыми: если карта структурно модифицированная в любое время после создания итератора, любым способом, кроме метода собственного удаления итератора, итератор будет вызывать ConcurrentModificationException.

И определение структурной модификации можно найти там:

структурная модификация любая операция, которая добавляет или удаляет один или несколько сопоставлений; просто изменяя значение, связанное с ключом, который экземпляр уже содержит не структурной модификация

Наконец, стоит также чтения последнего абзаца:

Fail-быстрых итераторы бросить ConcurrentModificationExceptionс наилучшим усилием. Поэтому было бы неправильно писать программу, зависящую от этого исключения за ее правильность: отказоустойчивое поведение итераторов должно использоваться только для обнаружения ошибок.

Смежные вопросы