Jump to content
  • Advertisement
Sign in to follow this  
Addictman

[java] Annoying error java.util.ConcurrentModificationException

This topic is 5052 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This is basically what I am told: java.util.ConcurrentModificationException at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:448) at java.util.AbstractList$Itr.next(AbstractList.java:419) at java.util.AbstractCollection.remove(AbstractCollection.java:254) Now, I read the API and it does actually mentioned this Exception. However, I still really can't say what's causing it in my code.. I have an ArrayList, and I add/remove to/from it. That's basically it. At a seemingly random time, it decides to crash on me, and print out this exception. Any known pitfalls and pratfalls here? :)

Share this post


Link to post
Share on other sites
Advertisement
It means what it says :) You've tried to make two concurrent modifications to the same collection, which usually means:
- You're iterating over a collection in one place, and trying to modify (without using the iterator) it at the same time - usually hidden in some other method.

- You've got two threads that are using the same collection, and one is iterating over while the other modifying it.

The first is usually predictable and easily fixed. The second usually ends up showing up at seemingly random times so that sounds like what you've got this time. Remember that even if you don't actually create and threads yourself you still get other threads in the form of the AWT event handler etc.

Share this post


Link to post
Share on other sites
Quote:
Original post by OrangyTang
It means what it says :) You've tried to make two concurrent modifications to the same collection, which usually means:

- You're iterating over a collection in one place, and trying to modify (without using the iterator) it at the same time - usually hidden in some other method.


So basically if I have keyboard actions or mouse actions that modify the renderqueue (add/remove) while rendering (iteration)is going on, I'm fucked? :) sounds damn fragile. Since the listeners run on the AWT thread, I guess that indicates the problem of multithreading as well. such lovely business ;)

Oh well. Thanks for the clarification anyways!

Share this post


Link to post
Share on other sites
The short answer is that you have designed your program wrong if this ever happens and is non-trivial to solve.

Usually, anything that has to iterate over something that might change (e.g. the render thread has to read lots of data from different places) it makes a COPY to iterate over - because if it doesn't then you get effects similar to tearing anyway, so you should NEVER have a problem with the CCME (because your fix to make your rendering prettier avoids this problem).

E.g.

ArrayList readableCopy = (ArrayList) originalList.clone();

Share this post


Link to post
Share on other sites
Redmilamber, I tried cloning the ArrayList, just to test if that would fix it. It didn't, so I'm still lost I guess.

Right now, the rendering process iterates and calls methods on the cloned arraylist, so that the real list is not modified during iteration anymore.

Share this post


Link to post
Share on other sites
clone() won't work because it only returns a shallow copy of the collection. Which means both copies share the underlying data structure. You have 2 options to overcome this. Use the toArray method and use a for loop to go through the array. Or you can create your own copy:

//initialize
ArrayList drawList = new ArrayList();

//drawing
public void draw() {
drawList.clear();
drawList.addAll(objectList);

for(Iterator it=drawList.iterator();it.hasNext();) {
//draw it
}
}

Share this post


Link to post
Share on other sites
Or you can synchronize on the array list when you modify it. Or better still, create the list as a synchronized collection:


ArrayList myList = (ArrayList)Collections.synchronizedList(new ArrayList());


Share this post


Link to post
Share on other sites
Better yet, I took a completely different approach and made my own RenderQueue class based off of a primitive array. now, it not only works seamlessly, but it tuned off several milliseconds as well ;) So I am happy again.

Share this post


Link to post
Share on other sites
Quote:
Original post by Aldacron
Or you can synchronize on the array list when you modify it. Or better still, create the list as a synchronized collection:


Yes, except that synchronizing the ArrayList can cause a big performance hit.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!