简体   繁体   English

在不删除任何内容的同时获取并发修改异常

[英]Getting Concurrent Modification Exception while not removing anything

Im writing simple Tower Defence game in Java. 我正在用Java编写简单的塔防游戏。 Here is method which finds path from spawn (set in constructor) to nearest base. 这是找到从生成(在构造函数中设置)到最接近的基本位置的路径的方法。

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;
        }
    }
}

It may return array of next directions in which monster moved to get to base or null if there is no path. 它可能会返回下一个方向数组,怪物将沿着该方向移动到基本位置;如果没有路径,则返回null。 It goes through fields which are Field class objects. 它遍历作为Field类对象的字段。 On every field monster searches for possible moves and for every creates new monster with set direction. 在每个野外,怪物都会搜索可能的移动,并且每个人都会创建具有设定方向的新怪物。 New monster inherits also moves array to add to it its own direction and then give it to new monster and so on. 新怪物继承后还会移动数组以添加其自身方向,然后将其分配给新怪物,依此类推。 And my question is where in my code is possibility of concurrent mod ex? 我的问题是在我的代码中并发mod ex的可能性在哪里? And how can I prevent it? 我该如何预防呢?

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)

Iterators are fail fast, so cannot concurrently modify the collection if you are using an iterator over it to iterate the collection. 迭代器快速失败,因此,如果您在其上使用迭代器来迭代集合,则不能同时修改集合。 means using an iterator, you cannot iterate and modify the collection at the same time. 意味着使用迭代器,您无法同时迭代和修改集合。 like adding or removing something to the collections over which you are itearting. 例如向要创建的集合中添加或删除某些内容。

What is a fail fast iterator 什么是失败快速迭代器

Also see this question fail-fast iterator 另请参阅此问题故障快速迭代器

Try this, may solve your problem 试试这个,可能会解决您的问题

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

ArrayList implementation is not synchronized, You'll need to synchronize the access to your list. ArrayList实现未同步,您需要同步对列表的访问。 You can accomplish this either by synchronizing the encpasulating object or by using Collections.synchronizedList method. 您可以通过同步加密对象或使用Collections.synchronizedList方法来完成此操作。

Please check this for more information 请检查以获取更多信息

Inside the loop, consider adding your objects to a temporary list and afterwards (outside the loop) add to your original list. 在循环内部,请考虑将对象添加到临时列表,然后再将其添加到原始列表(在循环外部)。

You can't modify the list you are iterating on. 您无法修改要迭代的列表。 Example: 例:

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

It will throw a java.util.ConcurrentModificationException as well. 也会抛出java.util.ConcurrentModificationException。

For a more detailed information, please read the documentation: http://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html 有关更多详细信息,请阅读文档: http : //docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM