Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

This question already has an answer here:

So i'm trying to create simple gravity using LWJGL, but the application randomly crashes with the java.util.ConcurrentModificationExceptionexception. The strange thing is that is does not always happen at the same time. Sometimes it crashes instantly but other times it runs fine for 10 minutes before crashing.

Main game class:

public static ArrayList<Block> blocks;

public Game() {
    blocks = new ArrayList<Block>();

    for(int i = 0; i < 40; i++)
        blocks.add(new BlockTest(i, 21, new float[] {0.4f, 0.6f, 0.7f}, false, 0));

    spawnTimer.scheduleAtFixedRate(new TimerTask() {
          public void run() {
              spawnBlock();
          }
    }, 1000, 1000);
}
public void update() {
    for(Block b : blocks)
        b.update();
}

Block class:

/** Update block */
public void update() {
    if(hasGravity) {
        boolean colliding = false;

        for(Block b : Game.blocks)
            if(b.getBlockID() == 0) {
                if(Util.checkBlockCollision(this, b)) {
                    colliding = true;
                    setBlockID(0);
                }
            }

        if(fallDelay.over() && !colliding) {
            setBlockYPosWithoutBlockSize(y += 2);
            fallDelay.start();
        }
    }
}

The stack trace is the following:

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)
    at snakybo.gravitytest.block.Block.update(Block.java:26)
    at snakybo.gravitytest.Game.update(Game.java:34)
    at Main.gameLoop(Main.java:52)
    at Main.main(Main.java:21)

With (Game.java:34) being this line:

b.update();

And (Block.java:26) being:

for(Block b : Game.blocks)

If you need the full code, it's available on Github

share|improve this question

marked as duplicate by RAS, РСТȢѸФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ, RobV, chrylis, Soner Gönül Oct 1 '13 at 14:26

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

    
Also, according to the Oracle Docs it mostly happens when using multithreading but i'm not multithreading here. –  Snakybo May 4 '13 at 12:17

1 Answer 1

up vote 3 down vote accepted

You are multithreading. The TimerTask runs on a separate thread.

What happens is this: the spawnBlock method that is being called on the timer task thread modifies the blocks list(adds one to the list). On the main thread, the update method is called, in which the code iterates over the blocks list.

Because a block is added to the blocks list during that iteration(during the spawnblock method execution on the other thread), you get the concurrentModificationException.

Replacing "for(Block b : blocks)" by "for(Block b : new ArrayList(blocks))" is a very simple but not so performant solution: since you always iterate over a new copy, you can modify the original list as much as you want.

A better solution is probably to start making your methods synchronized or rethink your design, like wrapping the blocks list in a synchronized wrapper.

share|improve this answer
    
Okay, didn't know the TimerTask runs on a seperate thread, thanks for the info i'll have to look into that synchronized wrapper, but for now for(Block b : new ArrayList(blocks)) seems to have fixed it. Thanks –  Snakybo May 4 '13 at 12:45

Not the answer you're looking for? Browse other questions tagged or ask your own question.