java.util.ConcurrentModificationException是一个大问题,在这种情况下

时间:2012-05-26 16:05:46

标签: java concurrentmodification

当我打电话给repaint();

时,我注意到我随机获得了Exception,因此我正在为我的决赛制作游戏

这一切的原因是不同的对象在不同的​​时间更新并且有自己的Thread来更新自己。有时,实体会在绘制时自行更新。绘制线程以大约60-100 FPS运行,而实体大约每300毫秒更新一次。

游戏不会停止或有任何与此相关的问题。

我知道忽略它是一个坏主意,但还有什么我可以做的吗?有多个线程是我能想到的唯一解决方案,可以让游戏发挥作用。

感谢阅读!

编辑:当我在绘画时尝试删除实体时,问题似乎发生了;两者都使用相同的列表。

2 个答案:

答案 0 :(得分:6)

ConcurrentModificationException与多线程无关(尽管可能涉及多个线程)。当您通过除List方法之外的方式添加或从集合中删除项目时,在迭代集合(例如Iterator.remove())时会发生这种情况。

这可能发生在不同的线程上,但它可能是同一个线程。例如,这段代码也会抛出一个ConcurrentModificationException:

Iterator iter = someList.iterator();
while(iter.hasNext()) {
   Object item = iter.next();
   someList.remove(item);
}

如果调用了iter.remove(),则不会发生错误。

避免这种情况的方法:

  1. 在迭代之前复制一份列表
  2. 仅使用迭代器的remove()方法
  3. 使用像CopyOnWriteArrayList之类的内容来避免此错误,代价是在每次更改时创建内部数组的副本。

答案 1 :(得分:1)

多线程的主要问题恰恰在于确保尽管对象的状态在多个线程之间共享,但这种状态始终保持一致。这就是同步块存在的原因,为什么存在锁,为什么存在volatile变量。

只是忽略了这个问题,希望不会出现严重问题,这是灾难的一个方法。一切都会好运1小时,然后你会开始到处都是例外,错误的结果等等。

让两个线程同时访问同一个非线程安全列表的事实表明您的代码有问题。这显然是不正确的,应该一定要修复。

您应该同步对共享列表的访问。阅读有关Java中并发性的教程和书籍,因为当多个线程运行时,同步不是一个选项。