Возможно, это повторяющийся вопрос, но я немного запутался в 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));
}
}
Использовать итератор 'Set' вместо – MadProgrammer
Вы не должны изменять структуру коллекции в цикле, вы закончите с ConcurrentModificationException. «Как это исправить?» часть уже упоминается @MadProgrammer – TheLostMind
@TheLostMind Извините, но я вас не понимаю. – Amogh