Search code examples
javalibgdxconcurrentmodification

Java ConcurrentModificationException with abstract super class


So I understand why I get the error; I would like to know a work around if possible or an alternative!

So I have a class called SpriteRenderable which is used to sort and render all objects on screen, it contains the position and sprite for the instances.

public static ArrayList<SpriteRenderable> spriteRenderables;

SpriteRenderable also has a static function Render(SpriteBatch batch) which loops over this list to call the update function on each one.

public static void Render() {
    spriteBatch.begin();
    for (ListIterator<SpriteRenderable> iter = 
        spriteRenderables.listIterator(); iter.hasNext();) {
        SpriteRenderable spriteRenderable = iter.next();
        spriteRenderable.update(delta);
        spriteRenderable.sprite.draw(spriteBatch);
        }
    spriteBatch.end();
}

public abstract void update();

I have another class Player which extends the SpriteRenderable class, so it's automatically added to the static ArrayList, and updated every render cycle. This is the same as the Gun and Bullet class as well.

The Gun class and Bullet class extend SpriteRenderable as well. Within the Player classes update function, if (Gdx.input.isButtonPressed(Input.Buttons.LEFT)) then the Guns shoot method is called which in tern calls Bullet shot = new Bullet();

This works fine until Player is updated, and the player fires the gun; the instantiated bullets are added to the static ArrayList while looping through itself. Causing :

Exception in thread "LWJGL Application" java.util.ConcurrentModificationException

I've tried surrounding the foreach(SpriteRenderable) loop with a try and catch; however this ends up not rendering any of the sprites due to the exception.


Solution

  • Assuming you iterate more through the list than modify it, you'd be good with CopyOnWriteArrayList. Any modifications during the lifetime of the iterator will not be visible to the iterator, however.