当前位置:
首页 >
Exception in thread “Thread-2“ java.util.ConcurrentModificationException异常的解决方案
发布时间:2024/3/12
73
豆豆
生活随笔
收集整理的这篇文章主要介绍了
Exception in thread “Thread-2“ java.util.ConcurrentModificationException异常的解决方案
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
ConcurrentModificationException异常的解决方案
- ConcurrentModificationException异常
ConcurrentModificationException异常是并发修改异常,最常见的出现情况是:在多线程的程序中,一边使用迭代器遍历,一边又对迭代器种的元素进行修改
- 异常产生背景
在上设计模式的课程中,老师以飞机大战为题材让我们熟悉运用设计模式,其中在写玩家飞机的子弹和敌机的碰撞函数中,我看到老师是直接使用普通的for循环,代码如下:
for (int i = 0; i < enemyPlanes.size(); i++) {EnemyPlane enemyPlane = enemyPlanes.get(i);for (int j = 0; j < fires.size(); j++) {Fire fire = fires.get(j);if ((fire.x + fire.image.getWidth() / 4) > enemyPlane.x && fire.x < (enemyPlane.x + enemyPlane.image.getWidth())&& fire.y < (enemyPlane.y + enemyPlane.image.getHeight()) && (fire.y+fire.image.getHeight()/4) > enemyPlane.y ) {//子弹打中敌机,子弹和敌机同时消失enemyPlane.remove();fire.remove();score++;}} }我就自认为可以使用增强for循环进行简化书写,代码如下:
for (EnemyPlane enemyPlane : enemyPlanes) {for (Fire fire : fires) {if ((fire.x + fire.image.getWidth() / 4) > enemyPlane.x && fire.x < (enemyPlane.x + enemyPlane.image.getWidth())&& fire.y < (enemyPlane.y + enemyPlane.image.getHeight()) && (fire.y+fire.image.getHeight()/4) > enemyPlane.y ) {enemyPlane.remove();fire.remove();score++;}} }结果在玩了一会游戏,就疯狂报ConcurrentModificationException异常了,结果如下:
-
异常产生原因分析:
要想了解这个异常的产生原因,就不得不了解增强for循环的底层实现原理了,也就是说得先了解迭代器(Iterator)!迭代器的设计原则是遵循:隔离性、独立性
- 隔离性: 如果集合增加、删除了元素,不能影响到已存在的迭代器
- 独立性 :是指不同迭代器遍历元素互不影响
这两种设计原则的目的就是为了保障迭代器的工作的规范性
而本题的问题就是出在迭代器的隔离性原则上,而实现隔离性原则有两种方式:
- 方式一:每次获取迭代器,都将待迭代的对象中的数据复制一份到迭代器中
- 方式二:在迭代器的类中设置一个成员变量,用来标记迭代器是否发生改变(这种方式有个专业名词:fail-fast机制)
显然方式二要优于方式一,Java官方也是采用方法二实现迭代器的隔离性原则的,见源码:
知道这些后,就能很清楚的明白为什么在hit方法中使用迭代器后,游戏进行一段时间就会报 ConcurrentModificationException异常了吧(●ˇ∀ˇ●),原因如下:
当游戏开始时,创建了一个迭代器,迭代器中有固定的元素了,然后当我们在期间进行了碰撞,进行了remove方法后子弹集合和敌机集合发生了改变,然后就导致迭代器遍历触发了checkForComodification()函数,导致直接报ConcurrentModificationException异常
-
解决方案:
- 方案一:改用普通for循环
拓展:
如果只是想修改一次集合的数据,并且不想报错,可以采用迭代器自带的remove方法
参考文章:
- Java Iterator(迭代器) | 菜鸟教程
- java迭代器
- CopyOnWriteArrayList详解
- Java CopyOnWriteArrayList详解
- Java迭代器Iterator的remove()方法的使用
总结
以上是生活随笔为你收集整理的Exception in thread “Thread-2“ java.util.ConcurrentModificationException异常的解决方案的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 论Web Service 相关技术
- 下一篇: 测试透射晶格分析的软件,透射电镜(TEM