Map迭代过程中remove引发的java.util.concurrentmodificationexception

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/pengchang_1981/article/details/8091562

     唉,基础还是不过硬,又在博客记录下一个小问题的解决思路。先贴出出错的代码,大家看看哪里会出问题:

      

// 定义的一个map常量
private static final Map<AlarmInfo, String> PLAN_ALARM_MAP = new LinkedHashMap<AlarmInfo, String>();

// 下面是处理过程
synchronized (PLAN_ALARM_MAP) {
                        logger.infoT("PLAN_ALARM_MAP size " + PLAN_ALARM_MAP.size());
			Set<AlarmInfo> set = PLAN_ALARM_MAP.keySet();
                        for (AlarmInfo alarmInfo : set) {
				if (!checkContinueAlarm(alarmInfo,
						PLAN_ALARM_MAP.get(alarmInfo))) {
					logger.infoT("clear planTask alarm!");
					// 清除告警信息
					manageAlarm(alarmInfo, mesg, true);

					PLAN_ALARM_MAP.remove(alarmInfo);
					// 记录下来,后面删除
					// alarmDelete.add(alarmInfo);
				}
			}
}

         看出来了吧,和List一样,在循环迭代过程中是不能修改或者删除Map的key的,会引发java.util.concurrentmodificationexception,很有趣的是,就像api说的,在大部分情况下会引起该异常,但有时候不会出异常,至于这个原因没深入研究源码,就暂且不论。发现了异常,就要满足在循环迭代Map的keySet的过程中删除map中的符合条件key的别的解决办法,在网上查了下找到两套都能实现的办法:

          1 将要删除的key存到一个List中,在遍历完map的keySet后,再迭代这个存放删除key的List,逐一删除!

          2 采用Iterator迭代,在迭代遇到需要删除的key时,采用迭代器的remove()方法删除,也可以避免出现异常!

          方案1的解决代码如下:

         

private static final Map<AlarmInfo, String> PLAN_ALARM_MAP = new LinkedHashMap<AlarmInfo, String>();

synchronized (PLAN_ALARM_MAP) {

			logger.infoT("PLAN_ALARM_MAP size " + PLAN_ALARM_MAP.size());
			Set<AlarmInfo> set = PLAN_ALARM_MAP.keySet();
			List<AlarmInfo> alarmDelete = new ArrayList<AlarmInfo>();

			for (AlarmInfo alarmInfo : set) {
				if (!checkContinueAlarm(alarmInfo,
						PLAN_ALARM_MAP.get(alarmInfo))) {
					logger.infoT("clear planTask alarm!");
					// 清除告警信息
					manageAlarm(alarmInfo, mesg, true);


					// 记录下来,后面删除
					alarmDelete.add(alarmInfo);
				}
			}

			 // 进行删除 
			 for (AlarmInfo deleteAlarm : alarmDelete) {
			      PLAN_ALARM_MAP.remove(deleteAlarm);
			 }
		}
             方案2代码如下:

            

private static final Map<AlarmInfo, String> PLAN_ALARM_MAP = new LinkedHashMap<AlarmInfo, String>();

synchronized (PLAN_ALARM_MAP) {

			logger.infoT("PLAN_ALARM_MAP size " + PLAN_ALARM_MAP.size());
			Set<AlarmInfo> set = PLAN_ALARM_MAP.keySet();

			AlarmInfo tempAlarmInfo = null;
			for (Iterator<AlarmInfo> itr = set.iterator(); itr.hasNext();) {

				tempAlarmInfo = itr.next();
				if (!checkContinueAlarm(tempAlarmInfo,
						PLAN_ALARM_MAP.get(tempAlarmInfo))) {
					logger.infoT("clear planTask alarm!");
					// 清除告警信息
					manageAlarm(tempAlarmInfo, mesg, true);
					itr.remove();
				}
			}
		}

                 参考文献:

                 http://yulimeander.i.sohu.com/blog/view/142269299.htm

                 http://swincle.iteye.com/blog/746980

                

猜你喜欢

转载自blog.csdn.net/pengchang_1981/article/details/8091562
今日推荐