Home > other >  ConcurrentModificationException with GUI
ConcurrentModificationException with GUI

Time:12-07

I am developing a classic arcade game called "Asteroids" as a final project in my college. Lately I ran into a problem where I try to draw the Balls in the game and I'ts throwing ConcurrentModificationException as a result of trying to draw the balls. It seems that it only happens when I draw the balls and not other objects like the player or the asteroids or the spaceships. I tried to figure it out with google but the problem isn't fixed. I also tried to put the synchronized keyword near the function and still there is no success.

The code is below, thanks for the helpers.

`

private synchronized void drawBullets(Graphics g){
   if (!bulletsList.isEmpty()) {
      for (Ball ball : bulletsList) {
         if (ball.getSize() > 0) {
            if (ball.isAlive())
               ball.drawBall(g);
         }
      }
   }
}

`

I've searched on google about this exception, it seems that the optimal approach to this excpetion is to not make any changes on the object while the loop iterates on this specific object. I've figured out that the only piece of code that I change a ball object is where a ball and another game object make a collision between them, but what seems weird is that I change the other objects as well when a collision happens and there is no such problem with them.

CodePudding user response:

The compiler effectively transforms your for loop into this:

Iterator<Ball> iterator = bulletsList.iterator();
while (iterator.hasNext()) {                        // Could throw
    Ball ball = iterator.next();                    // Could throw
    if (ball.getSize()>0 && ball.isAlive()) {
        ball.drawBall(g);
    }
}

If your program modifies the bulletsList after the iterator is created, then any attempt to use the iterator likely will throw the exception. The only way to prevent that from happening is to make sure that nothing (e.g., no other thread) modifies the list until the loop has finished.


I also tried to put the synchronized keyword near the function and still there is no success.

synchronized does not do anything at all unless two or more threads try to enter blocks that are synchronized on the same object at the same time.

When you write synchronized void drawBullets(Graphics g)... the synchronized block is the whole body of the drawBullets function, and the object on which it synchronizes is this.

What object is this when drawBullets is called? and what other thread synchronizes on the same object?


I've figured out that the only piece of code that I change a ball object is where a ball and another game object make a collision between them.

Modifying Ball objects will not cause the ConcurrentModificationException to be thrown. It won't even be thrown if you modify Ball objects that are members of the bulletsList. The only way the exception will be thrown is if some other code modifies the list itself while your drawBullets method is iterating over it. In order to get the exception, the other thread must call bulletsList.add(...), or .remove(), or .clear(), or .set(...), etc.

  • Related