语言:Java
问题:异常类问题
问题
从现场拿回的日志中报了一个ConcurrentModificationException的异常,第一次遇到这个异常,分析一下。
问题分析
关于该异常产生的原理和Java中的源码,可以参考Java ConcurrentModificationException异常原因和解决方法,这个帖子已经说的很详细了,并且源码解析的也很好。
我们精简一下异常产生的原因为:对Vector、ArrayList在迭代的时候,如果同时对其进行修改,就会产生这个异常。
看过上面的帖子或者其余类似的贴子,基本上都有这么一个demo:
public class Test {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(2);
Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()){
Integer integer = iterator.next();
if(integer==2)
list.remove(integer); //重点再此处进行修改了
}
}
}
也就是所谓的在迭代中进行删除导致这个异常。
问题寻找和解决
参考上面的demo,观察自己的代码,单线程,仅仅只有一个遍历,并没有什么删除的操作,在开发过程中也没有遇到这个异常。代码精简过后如下:
Constants.getList(); //获取集合
for(String modelName : Constants.list) { //遍历集合
...
}
那么这么一段常见的代码怎么会遇到这个问题呢?
略微思考后,发现问题原因出现在静态变量上面Constants.list是一个静态变量,所以虽然是单线程,也会出现这个异常。
假设两个人访问,一个人访问还没完成,另一个又进行Constants.getList();操作给集合赋值,自然会导致这个异常。
略作修改后即可解决,将代码改为:
if (!Constants.listNoNull()) Constants.getList(); //重点 修改的地方
for(String modelName : Constants.list) { //遍历集合
...
}
反思总结
在使用静态变量的时候一定要主要静态变量的特性,即类加载时完成初始化,它在内存中仅有一个,且JVM也只会为它分配一次内存,所有类共享该静态变量。
小计
ConcurrentModificationException也是一个unchecked exception,可以参考上一篇帖子如何理解java中checked exception和unchecked exception。
网友评论