Jump to content
  • Advertisement
Sign in to follow this  
Code Sage

CopyOnWriteArrayList

This topic is 1320 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

I am attempting to create a ComponentHandler, which extends MouseAdapter, that essentially handles all the buttons in my game. Every time a new Component is created it is put in to an ArrayList inside ComponentHandler. This ArrayList is iterated through inside mouseMoved() and mousePressed() in order to identify the component and handle what happens to it when it is clicked/hovered over. Randomly when I start up my game I get a ConcurrentModificationException inside mouseMoved(). Sometimes it can be the first time starting it other times it could be the 50th. I can't for the life of me figure out the problem, so I am considering just using a CopyOnWriteArrayList and hoping that solves the issue. Do you think that would be the optimal fix for this? Or am I completely derping out and missing something totally obvious? I also have methods in ComponentHandler that getComponent, addComponent, removeComponent, getComponentList. Currently I am only using getComponent inside and outside of ComponentHandler. If you need to know anything just let me know and I will be glad to tell you. Thanks for your time and help.

Share this post


Link to post
Share on other sites
Advertisement

When do components get added?  Or removed.   My guess offhand is that one of those is getting called while you're busy iterating over the list in a mouse move.  

Share this post


Link to post
Share on other sites

When do components get added?  Or removed.   My guess offhand is that one of those is getting called while you're busy iterating over the list in a mouse move.  

 

Components get added and removed whenever there is state change. At initialization of every state I clear the list and than it gets filled with whatever components are necessary for that state of the game. For the time being I ended up making the list CopyOnWriteArrayList and it has been working perfectly fine. It may not be a legit fix but, if it works it works I guess haha. If someone has a better solution though I am more than happy to hear it.

Edited by Code Sage

Share this post


Link to post
Share on other sites


ConcurrentModificationException inside mouseMoved().

 

This is a terrible exception name.  Not only can you modify something in two different threads, but just iterating over the collection and trying to change something can cause this.  It may not have anything to do with multiple threads.

Share this post


Link to post
Share on other sites

ConcurrentModificationException inside mouseMoved().

 
This is a terrible exception name.  Not only can you modify something in two different threads, but just iterating over the collection and trying to change something can cause this.  It may not have anything to do with multiple threads.

So is my fix sufficient? Or is the whole thing a mistake in the first place..

Share this post


Link to post
Share on other sites

 

 

ConcurrentModificationException inside mouseMoved().

 
This is a terrible exception name.  Not only can you modify something in two different threads, but just iterating over the collection and trying to change something can cause this.  It may not have anything to do with multiple threads.

So is my fix sufficient? Or is the whole thing a mistake in the first place..

 

 

If it was me I would undo the fix and see if I could find the problem.  Without seeing the code I can't tell you if this has fixed the problem or just hidden it.

Share this post


Link to post
Share on other sites

ConcurrentModificationException inside mouseMoved().

 
This is a terrible exception name.  Not only can you modify something in two different threads, but just iterating over the collection and trying to change something can cause this.  It may not have anything to do with multiple threads.

So is my fix sufficient? Or is the whole thing a mistake in the first place..
 
If it was me I would undo the fix and see if I could find the problem.  Without seeing the code I can't tell you if this has fixed the problem or just hidden it.

I could send you my code if you wouldn't mind looking over it for me. Just promise I won't see it in the coding horrors section later haha.

Share this post


Link to post
Share on other sites


I could send you my code if you wouldn't mind looking over it for me. Just promise I won't see it in the coding horrors section later haha.

 

Don't do that.  Instead, post the smallest example you can that still produces the bug.  That way others can learn from it.

Share this post


Link to post
Share on other sites


Don't do that.  Instead, post the smallest example you can that still produces the bug.  That way others can learn from it.

 

I have been trying to recreate it for a while and I simplified it down as far as possible, but now the exception is never thrown... Honestly as I keep adding more and more trying to throw the exception I will have figured out the problem by the time it happens. I'll make a post if I figure it out, but I don't think i'll post any code unless you wanna take a look at my full source.

Share this post


Link to post
Share on other sites

Are you using the for(var: collection) construct to iterate? That silently creates an Iterator, which throws ConcurrentModificationException if you modify the collection it is backed by.

 

If you are removing the element you are examining, such as below, then you should explicitly create an iterator and use its remove() method.

Iterator<Foo> iter = fooArrayList.iterator();
while( iter.hasNext() ) {
    Foo e = iter.next();

    if( e.isBar() ) {
        iter.remove();
    }
}

Alternatively, simply build up a list of elements that must be removed, and then remove them one by one after you finish iterating through the list of elements.

 

Finally, if the elements are UI components in a Swing or AWT hierarchy, and you absolutely positively cannot be sure whether you are in an event handler or not while iterating on your collection, you can make sure you don't modify the view from inside the event handler thread by using the SwingUtilities.invokeLater() method.

for(Foo e: fooCollection) {
    if( e.isBar() ) {
        SwingUtilities.invokeLater(new Runnable() {
            void run() {
                fooCollection.remove(e);
            }
        });
    }
}

Disclaimer: I do not claim that any of the above suggestions meet best practices; only that they let you avoid modifying a collection while it is being iterated over.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!