Sometimes receiving java.util.ConcurrentModificationException, sometimes not. Can't figure out why

StackOverflow https://stackoverflow.com/questions/22178464

  •  03-06-2023
  •  | 
  •  

سؤال

So firstly here are the error messages:

Exception in thread "Thread-2"
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at zom.mainpac.Game.render(Game.java:218)
at zom.mainpac.Game.run(Game.java:154)
at java.lang.Thread.run(Unknown Source)

Rendering my ArrayList of Objects at Line 218:

    for(Objects e : list){
    e.render(g);
    }

And then my render function at line 154:

    render();

...

private void render() {

    BufferStrategy bufferStrategy = this.getBufferStrategy();

    if (bufferStrategy == null) {

        this.createBufferStrategy(2);
        return;

    }

The problem is probably because my laptop cant render all of the Objects SOMETIMES, so it gives up. So im just wondering if there is a better way I can do this without it crashing all the time.

هل كانت مفيدة؟

المحلول 2

The problems happens because your code modifies the list while iterating.

  • If you have only one thread which reads/writes from/to the list, then the most likely the call

    this.createBufferStrategy(2);

sometimes adds some elements to the same array list. You could fix the exception if you will use a copy of the list to iterate:

for (Objects e : new ArrayList(list)) {
   e.render(g);
}
  • If you have MORE than one thread to read/write the list, use java.util.concurrent.CopyOnWriteArrayList instead

نصائح أخرى

You have a thread safety issue and/or list access issue. You may want to copy the list/array items into a local variable so your list cannot be modified while you traverse and/or consider synchronization block.

Your instance list variable is being accessed by one thread (performing the for loop) and then another thread comes along and maybe it wants to access it. To solve instead of performing a for loop using the instance variable create a local variable and copy the items from the .list. now you have a private list that no other thread can access

The For each uses an iterator to do it's looping, so you're susceptible to such exceptions during iteration if you happen to remove something from that list. This can happen for example if you are removing a tile or sprite from your list in your game while rendering. If you are not modifying the List that often you could use a CopyOnWriteArrayList if you wish to modify the List while iterating (let's you not have to create a copy of the list), but it's important to note you should first understand the behavior that causes this and not use a blind fix.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top