0

并发修改异常错误给我带来了很多麻烦。在社区的帮助下,我设法修复了我的最后一个错误,但我认为这个错误更令人费解。

我现在在绘画时遇到并发修改错误,我担心这个错误发生在绘画函数本身。与我上次的错误不同,我不想删除一个实体,在那种情况下,我完全理解发生了什么,只是不知道如何修复它,另一方面,这个错误我不明白。

 TowerItr = activeTowers.iterator();

            while (TowerItr.hasNext()) {
                try {

                theTower = (ArcherTower) TowerItr.next();


                g.drawImage(tower, theTower.y * Map.blockSize, theTower.x * Map.blockSize, this);

                } catch (ConcurrentModificationException e) {


                }
            }

抛出异常的那一行是:theTower = (ArcherTower) TowerItr.next();

4

2 回答 2

4

ConcurrentModificationException (CME) 总是有两个方面,并且只有一个方面报告错误。

在这种情况下,您的代码看起来非常好。您正在遍历 activeTowers 的成员。

堆栈跟踪将向您显示您不知道的任何内容......您拥有 CME。

您需要了解的是activeTowers 集合中添加/删除数据的位置。

在许多情况下,有相当简单的修复。一个可能的解决方法是在每个使用它的地方同步对 activeTowers 数组的访问。这可能很难做到。

另一种选择是使用 java.util.concurrent.* 包中的集合,并使用 toArray(...) 方法获取集合的快照,然后您可以在 while 循环中迭代该快照。

// activeTower must be something from java.util.concurrent.*
for (ArcherTower theTower : activeTower.toArray(new ArcherTower[0]) {
    g.drawImage(tower, theTower.y * Map.blockSize, theTower.x * Map.blockSize, this);
}

我应该补充一点,如果您使用 java.util.concurrent.* 集合,那么 iterator() 也将返回一个“稳定”迭代器(不会抛出 CME,并且可能(或可能不会)反映集合中的更改)

底线是 CME 只告诉你故事的一半……而只有你的代码会告诉你其余的……

于 2013-05-18T02:07:51.117 回答
0

继续我们尊敬的成员的建议:

1)这个错误一般是在提取Listan 后修改时出现。Iterator

2) 我正在查看您的代码,除了thisdrawImage()方法中使用之外,它似乎没问题。这可能会改变您的List因为This可以直接访问class members / class variables.

3)如果多个线程同时访问,也会发生这种情况List。并且其中一个线程可能正试图List从共享相同实例的其他方法中更改您的List. I am saying some other method because concurrent read access should not create trouble if multiple threads were accessing this method.

注意:请所有可能的代码和 Stake 跟踪来调试确切的问题。

于 2013-05-18T02:25:13.853 回答