项目场景:
项目背景:从Redis缓存取某时间段内的历史数据
问题描述
数据传输过程中数据不时出现丢失的情况,偶尔会丢失一部分数据
public HashMap<Integer, List<Float>> getTagHistoryCacheData(HashMap<Integer, Integer> tagIds) {
HashMap<Integer, List<Float>> dataListMap = new HashMap<>();
for (Integer tagId : tagIds.keySet()) {
if (historyDataCache.containsKey(tagId)) {
List<Float> dataList = historyDataCache.get(tagId);
dataListMap.put(tagId, historyDataCache.get(tagId).subList(dataList.size() - tagIds.get(tagId), dataList.size()));
}
}
return dataListMap;
}
原因分析:
调试发现在这个方法中偶尔会出现ConcurrentModificationException异常,子集合先引用原集合,引用之后再对原集合进行了操作(改变了原集合的结构),此时操作使用子集合就会出现该异常!
解决方案:
将子集合拷贝到新集合中,然后直接操作使用该新集合,不要去引用原集合,除非能保证引用的原集合在引用之后不再操作(改变结构)
public HashMap<Integer, List<Float>> getTagHistoryCacheData(HashMap<Integer, Integer> tagIds) {
HashMap<Integer, List<Float>> dataListMap = new HashMap<>();
for (Integer tagId : tagIds.keySet()) {
if (historyDataCache.containsKey(tagId)) {
List<Float> dataList = historyDataCache.get(tagId);
List<Float> copyList = new ArrayList<>();
copyList.addAll(historyDataCache.get(tagId).subList(dataList.size() - tagIds.get(tagId), dataList.size()));
dataListMap.put(tagId, copyList);
}
}
return dataListMap;
}