记一次java中ConcurrentModificationException异常处理和解决

语言:Java
问题:异常类问题

问题

从现场拿回的日志中报了一个ConcurrentModificationException的异常,第一次遇到这个异常,分析一下。

问题分析

关于该异常产生的原理和Java中的源码,可以参考Java ConcurrentModificationException异常原因和解决方法,这个帖子已经说的很详细了,并且源码解析的也很好。

我们精简一下异常产生的原因为:对Vector、ArrayList在迭代的时候,如果同时对其进行修改,就会产生这个异常。

看过上面的帖子或者其余类似的贴子,基本上都有这么一个demo:

public class Test {
    public static void main(String[] args)  {
        ArrayList list = new ArrayList();
        list.add(2);
        Iterator 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。

END

参考

Java ConcurrentModificationException异常原因和解决方法

你可能感兴趣的:(记一次java中ConcurrentModificationException异常处理和解决)