Java: java.util.ConcurrentModificationException - PullRequest
3 голосов
/ 24 февраля 2012

Я делаю 2D и в настоящее время работаю над стрельбой пулями.Пуля это отдельный класс.Все пули хранятся в массиве, называемом пулями.Я пытаюсь заставить его уничтожить себя, когда он находится за пределами экрана (<-16), но при попытке это выдает мне эту ошибку.</p>

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
at java.util.AbstractList$Itr.next(Unknown Source)
at GameCanvas.updateMovement(GameCanvas.java:94)
at GameCanvas.gameLoop(GameCanvas.java:63)
at GameCanvas.<init>(GameCanvas.java:28)
at GameClient.<init>(GameClient.java:68)
at GameClient.main(GameClient.java:29)

Я предполагаю, что это как-то связано с уничтожением, я использую этот код для его уничтожения:

public void move() {

    if(x > -16) {
        x -= move_speed;
    } else {
        kill();
    }

}

public void kill() {
    ObjectHandler.bullets.remove(this);
}

updateMovement () метод:

public void updateMovement() {
    PlayerObject.update();

    for(Bullet bullet : ObjectHandler.bullets) {
        bullet.move();


    }

}

Почему он это делает?Благодаря.

Ответы [ 4 ]

4 голосов
/ 24 февраля 2012

Это происходит потому, что вы изменяете список во время итерации по нему.

Попробуйте «запомнить», что вам нужно kill, и после того, как вы пройдете весь список, просмотрите«память» и выполнить соответствующие kill с.Таким образом, вы измените список после итерации по нему.

Например:

public void move() {

    if(x > -16) {
        x -= move_speed;
    } else {
        ObjectHandler.remember_to_kill(this);
    }

}

// in ObjectHandler:

private HashSet<type_of_object_to_kill> kill_memory = new...;

public void remember_to_kill() {
    this.kill_memory.add(this);
}

private void kill_from_memory() {
    for (type_of_object_to_kill obj: kill_memory) {
        ObjectHandler.bullets.remove(this);
    }
    ObjectHandler.kill_memory.clear();
}

// update movement:

public void updateMovement() {
    PlayerObject.update();

    for(Bullet bullet : ObjectHandler.bullets) {
        bullet.move();
    }
    ObjectHandler.kill_from_memory();
}
2 голосов
/ 24 февраля 2012

Из трассировки стека видно, что у вас есть метод gameLoop(), который вызывает updateMovement() в GameCanvas.Последний перебирает пули в потоке main.В то же время ваш метод kill() изменяет список.Это именно то, что говорит исключение, и предотвращает дальнейшее повреждение.

Вы должны синхронизировать доступ к списку bullets или использовать потокобезопасный сбор, например CopyOnWriteArrayList.

0 голосов
/ 25 февраля 2012

Проблема в том, что вы пытаетесь изменить коллекцию, удаляя элемент во время чтения. Конечно, это может быть опасно, и поэтому исключение выбрасывается. Если вы используете iterator, вы можете использовать его функции для удаления текущего элемента.

Примерно так:

public void updateMovement() {
    PlayerObject.update();

    Iterator<Bullet> iterator = ObjectHandler.bullets.iterator();
    while(iterator.hasNext()) {
        Bullet bullet = iterator.next();
        if(x > -16) {
            x -= move_speed;
        } else {
            iterator.remove();
        }
    }
}
0 голосов
/ 24 февраля 2012

Обычно это выдается, когда вы перебираете список и одновременно пытаетесь удалить / изменить элемент из списка.Я не уверен, что именно происходит.Было бы полезно больше примеров кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...