以下代码抛出并发修改异常,异常所指向的行是for循环的第一行
private synchronized void updateAllCacheValues() {
for (Map.Entry<Configurations, SalesConfiguration> entry : ConfigurationCache.entrySet()) {
Configurations conf = entry.getKey();
SalesConfiguration saleConfiguration = ConfigurationCache.get(conf);
Map<String, String> newMap = generateKeyValueMapFromConfigurations(conf);
lastLoadTimestamp = new Date();
saleConfiguration.setMap(newMap, lastLoadTimestamp);
}
logger.debug("Successfully updated all cached configurations., cache size " + ConfigurationCache.size() + "LAST_LOAD_TIME" + lastLoadTimestamp);
}
以下是异常追踪
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429)
at java.util.HashMap$EntryIterator.next(HashMap.java:1463)
at java.util.HashMap$EntryIterator.next(HashMap.java:1461)
at com.learning.java.daily.updateAllCacheValues(ConfigurationLoader.java:237)
at com.learning.java.daily.updateAllCacheValues.impl.ConfigurationLoader.loadConfigurations(ConfigurationLoader.java:156)
我无法猜出是什么导致了这个异常,因为我编写了一个示例测试,我在修改Map值的属性,但没有出现并发修改异常。
答案 0 :(得分:1)
要回答标题中的问题:否,修改HashMap
中的值对象,而迭代条目集不能单独生成ConcurrentModificationException
}。必须有其他事情发生。
对generateKeyValueMapFromConfigurations()
或saleConfiguration.setMap()
的调用是否可以修改地图?可能是你的ConfigurationCache
可以被其他一些并发线程修改?我知道我只是猜测,这是我们用手头的信息做的最好的。
答案 1 :(得分:0)
我认为这条线是罪魁祸首。
saleConfiguration.setMap(newMap, lastLoadTimestamp);
字面上ConcurrentModificationException来自迭代它时更新地图条目。你能否请注释掉那一行并检查你是否再次获得例外?如果不是,则需要更改逻辑,以便在迭代它们时不更改映射条目。
答案 2 :(得分:0)
您正在迭代入口集。因此,在迭代时不允许修改入口集值。使用ConcurrentHashMap而不是HashMap。
这是分析。
我们可以修改键/值的属性。但是我们不能通过在迭代时向地图添加或删除元素来修改地图。假设一个地图有五个元素,当我们迭代它时,我们既不能添加元素来映射也不能从地图中删除元素。为此,我们应该使用ConcurrentHashMap。
希望现在更清楚。