2014-06-23 3 views
1

Возможно, это повторяющийся вопрос, но я немного запутался в ConcurrentModificationException. Я рассмотрел некоторые другие вопросы о переполнении стека и некоторые статьи, связанные с тем, как избежать ConcurrentModificationException. Я узнаю, что это исключение возникает при циклизации в коллекции AND, изменяя то же самое (наиболее распространенная проблема с remove).ConcurrentModificationException on for loop on java.util.Set

Но в моем случае я просто зацикливаю (foreach) на java.util.Set, тогда я получу это исключение.

Кроме того, я не получаю это исключение всегда, когда я делаю нагрузочное тестирование моего веб-приложения с помощью Jmeter (150 пользователей в 5 секунд) в этом случае я получаю исключение

Вот мой код, где я получаю исключение по любому из трассировки стека из файла журнала

public static Map<String, String> getMessageMap(Locale locale) { 
    Properties properties; 
    Set<Object> objkeys; 
    Map<String, String> messageMap = null; 

    if (messageMap == null) { 
     messageMap = new HashMap<String, String>(); 
     // 1 Get properties file. 
     properties = Utility.loadPropertiesFile(locale); // this method return properties from static veriable 

     // 2 Get all keys of properties file. 
     objkeys = properties.keySet(); 

     // 3 Add all key values into map. 
     for (Object key : objkeys) { caught exception here 
      String keyName = key.toString(); 
      if (keyName.contains("global.")) { 
       messageMap.put(keyName, properties.getProperty(keyName)); 
      } 
     } 

    } 
    return messageMap; 
} 

Согласно файла журнала ConcurrentModificationException это произошло на линии for (Object key : objkeys)

Вот некоторые строки из трассировки стека

java.util.ConcurrentModificationException 
at java.util.Hashtable$Enumerator.next(Unknown Source) 
at com.utilities.MKCLUtility.getMessageMap(Utility.java:164) 
at com.utilities.MKCLUtility.addMessage(Utility.java:49) 
at com.controllers.LoginController.loginPost(LoginController.java:132) 

Что я могу сделать, чтобы этого избежать? и почему это исключение происходит, хотя я не изменяю набор.

Обновленный код

Iterator<Object> iterator = objkeys.iterator(); 
while (iterator.hasNext()) 
{ 
    String keyName = iterator.next().toString(); 
    if (keyName.contains("global.")) { 
     messageMap.put(keyName, properties.getProperty(keyName)); 
    } 
} 
+2

Использовать итератор 'Set' вместо – MadProgrammer

+0

Вы не должны изменять структуру коллекции в цикле, вы закончите с ConcurrentModificationException. «Как это исправить?» часть уже упоминается @MadProgrammer – TheLostMind

+0

@TheLostMind Извините, но я вас не понимаю. – Amogh

ответ

0

К руководством замечания по вопросу, который я изменен кода:

public static Map<String, String> getMessageMap(Locale locale) { 
    Properties properties; 
    Set<Object> objkeys; 


    if (messageMap == null) { 
     messageMap = new HashMap<String, String>(); 
     // 1 Get properties file. 
     properties = MKCLUtility.loadPropertiesFile(locale); 

     // 2 Get all keys of properties file. 
     objkeys = properties.keySet(); 

     // 3 Add all key values into map. 
     Iterator<Object> iterator = objkeys.iterator(); 
     while (iterator.hasNext()) 
     { 
      String keyName = iterator.next().toString(); 
      if (keyName.contains("global.")) { 
       messageMap.put(keyName, properties.getProperty(keyName)); 
      } 
     } 
    } 
    return messageMap; 
} 

Я сделал messageMap как статические, так эта функция по первому требованию будет проверять null, если он является недействительным, то messageMap наполняются то для следующий запрос будет напрямую возвращен messageMap.

При этом ConcurrentModificationException разрешается.

Но все же Если их предложение, которое вы хотите дать тогда, Plzz мне хотелось бы знать.

-2

Вы изменить messageMap карту в то время как итерация это цифровой телефон. Вот почему вы получаете сообщение. Просто соберите соответствующие ключи внутри объекта ArrayList, затем переберите его и измените карту messageMap.

EDIT:

исключение фактически со ссылкой на messageMap и не properties. Связаны ли эти 2 каким-либо образом (общие ключи). Является ли код, не показанный здесь, итерацией более messageMap?

+0

Но я не думаю, что я изменяю карту свойств. На какой строке я его модифицирую. Как вы сказали, я беру все свои ключи в другом 'set' и итерации на нем' objkeys = properties.keySet(); ' – Amogh

+0

В комментариях к вопросу добавляется разъяснение о messageMap, а не свойствах, и я не повторяю MessageMap I я просто возвращаю его. – Amogh

+0

Создает ли новый код с помощью итератора CME? –