获取并发修改异常而不删除任何内容

时间:2013-01-29 09:47:07

标签: java exception concurrency

我用Java编写简单的塔防游戏。这是从spawn(在构造函数中设置)到最近的基础查找路径的方法。

public int[] findPath(Field startField) {
    ArrayList<TestMonster> monsrs = new ArrayList<TestMonster>();
    TestMonster first = new TestMonster(startField.getCenter(), getStartingDirection(startField), new int[0]);
    monsters.add(first);
    while (true) {
        for (TestMonster monsr : monsrs) {
            monster.move();
            if (getFieldFromCenter(monsr.getPoint()).getState() == 101)
                return monsr.getPath();
            Field field = getFieldFromCenter(monsr.getPoint());
            if (field.isUp())
                monsters.add(new TestMonster(monsr.getPoint(), 0, monster.getPath()));
            if (field.isRight())
                monsters.add(new TestMonster(monsr.getPoint(), 90, monster.getPath()));
            if (field.isDown())
                monsters.add(new TestMonster(monsr.getPoint(), 180, monster.getPath()));
            if (field.isLeft())
                monsters.add(new TestMonster(monsr.getPoint(), 270, monster.getPath()));
            if (monsrs.isEmpty())
                return null;
        }
    }
}

如果没有路径,它可能返回怪物移动到底部的下一个方向的数组或null。它遍历Field类对象的字段。在每个场上,怪物都会搜索可能的移动,并为每个场景创建具有设定方向的新怪物新怪物继承也移动数组添加它自己的方向然后把它给新怪物等等。而我的问题是我的代码中可能存在并发mod ex的可能性?我该如何预防?

STACK TRACE:

Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
at java.util.ArrayList$Itr.next(ArrayList.java:791)
at towerdefence.MainPanel.findPath(MainPanel.java:160)
at towerdefence.MainPanel$1.actionPerformed(MainPanel.java:62)
at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1664)
at javax.swing.JComponent.processKeyBinding(JComponent.java:2879)
at javax.swing.KeyboardManager.fireBinding(KeyboardManager.java:306)
at javax.swing.KeyboardManager.fireKeyboardAction(KeyboardManager.java:250)
at javax.swing.JComponent.processKeyBindingsForAllComponents(JComponent.java:2971)
at javax.swing.JComponent.processKeyBindings(JComponent.java:2963)
at javax.swing.JComponent.processKeyEvent(JComponent.java:2842)
at java.awt.Component.processEvent(Component.java:6282)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)

3 个答案:

答案 0 :(得分:1)

迭代器快速失败,因此如果您使用迭代器迭代集合,则无法同时修改集合。表示使用迭代器,您不能同时迭代和修改集合。比如在你正在迭代的集合中添加或删除某些东西。

What is a fail fast iterator

另请参阅此问题fail-fast iterator

答案 1 :(得分:0)

试试这个,可以解决你的问题

List<TestMonster> monsrs = Collections.synchronizedList(new ArrayList<TestMonster>());

ArrayList实施未同步,您需要同步对列表的访问权限。 您可以通过同步包含对象或使用Collections.synchronizedList方法来完成此操作。

请查看this了解详情

答案 2 :(得分:0)

在循环内部,考虑将对象添加到临时列表中,然后(在循环外)添加到原始列表中。

您无法修改正在迭代的列表。例如:

List<Object> list = new ArrayList<Object>();
list.add("object 1");
list.add("object 2");
for (Object object : list) {
    list.add("another one");
}

它也会抛出java.util.ConcurrentModificationException。

有关更多详细信息,请阅读文档: http://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html