Thread: Arraylist concurrent modification exception

Page 1 of 2 12 LastLast
Results 1 to 10 of 11
  1. #1 Arraylist concurrent modification exception 
    Community Veteran

    mige5's Avatar
    Join Date
    Aug 2008
    Posts
    5,528
    Thanks given
    573
    Thanks received
    1,410
    Rep Power
    2114
    EDIT: solved.

    The situation I have is that theres bunch of methods which need to loop through the partyMembers arraylist and those methods can add and remove from the list, and its possible to have multiple events happening in the same time, and because of that there might be 2 methods looping through the list at once, and if theres anything to add or remove from the list, it will end up with exception... is there something I could do to make it work as intended?

    Heres an example method:
    Code:
    public ArrayList<Player> partyMembers = new ArrayList<Player>();
    
    public void exampleMethod(){
    		Iterator<Player> iter = partyMembers.iterator();
    		while (iter.hasNext()) {
    		    Player member = iter.next();
    		    if (membersToRemove.contains(member)){
    		        iter.remove();
    		        continue;
    		    }
    		    member.actionSender.sendMessage("This was an example method.");
    		}
    	}
    Number of page #1 releases with most views & posts: (Updated: 2023)
    RS2 server section: 1
    RS2 client section: 2
    Reply With Quote  
     

  2. #2  
    SERGEANT OF THE MASTER SERGEANTS MOST IMPORTANT PERSON OF EXTREME SERGEANTS TO THE MAX!

    cube's Avatar
    Join Date
    Jun 2007
    Posts
    8,871
    Thanks given
    1,854
    Thanks received
    4,745
    Rep Power
    5000
    Iterator<Player> iter = partyMembers.listIterator();

    Attached image

    Reply With Quote  
     

  3. Thankful users:


  4. #3  
    Respected Member


    Kris's Avatar
    Join Date
    Jun 2016
    Age
    26
    Posts
    3,638
    Thanks given
    820
    Thanks received
    2,642
    Rep Power
    5000
    Quote Originally Posted by S Quare Quxx View Post
    Iterator<Player> iter = partyMembers.listIterator();
    you what?
    Edit: nvm I'm drunk, thought you just referred the normal iterator. Yeah, listiterator will probably work too here.

    Seems like the only way to do what you're doing would be with a CopyOnWriteArrayList.
    It's not very efficient though, if you use the collection heavily, might want to reconsider your structure of the code.
    Attached image
    Reply With Quote  
     

  5. Thankful user:


  6. #4  
    Krator || Indie Dev

    Jordan Belfort's Avatar
    Join Date
    Dec 2012
    Posts
    1,051
    Thanks given
    535
    Thanks received
    485
    Rep Power
    1172
    Quote Originally Posted by Kris View Post
    you what?
    Edit: nvm I'm drunk, thought you just referred the normal iterator. Yeah, listiterator will probably work too here.

    Seems like the only way to do what you're doing would be with a CopyOnWriteArrayList.
    It's not very efficient though, if you use the collection heavily, might want to reconsider your structure of the code.
    Unrelated but at what point does CopyOnWriteArrayList become not efficient? Asking because I have used it before but never had any issues.
    Attached image
    [/CENTER]
    Reply With Quote  
     

  7. Thankful user:


  8. #5  
    Respected Member


    Kris's Avatar
    Join Date
    Jun 2016
    Age
    26
    Posts
    3,638
    Thanks given
    820
    Thanks received
    2,642
    Rep Power
    5000
    Quote Originally Posted by Jordan Belfort View Post
    Unrelated but at what point does CopyOnWriteArrayList become not efficient? Asking because I have used it before but never had any issues.
    As name states, it creates a new underlying arraylist every time a mutation operation is performed on the list. So if you heavily modify the contents, it might not be a good idea, especially if the collection is large.
    However the main benefit from using it is that it will never throw a concurrent modification exception, it is completely safe when it comes to that; if at all possible though, I'd avoid it; lots of unnecessary heap can cause gc to mess with your servers performance by causing spikes.
    Attached image
    Reply With Quote  
     

  9. Thankful users:


  10. #6  
    Community Veteran

    mige5's Avatar
    Join Date
    Aug 2008
    Posts
    5,528
    Thanks given
    573
    Thanks received
    1,410
    Rep Power
    2114
    Quote Originally Posted by Kris View Post
    As name states, it creates a new underlying arraylist every time a mutation operation is performed on the list. So if you heavily modify the contents, it might not be a good idea, especially if the collection is large.
    However the main benefit from using it is that it will never throw a concurrent modification exception, it is completely safe when it comes to that; if at all possible though, I'd avoid it; lots of unnecessary heap can cause gc to mess with your servers performance by causing spikes.
    well I dont think the list size will ever be larger than 20. (90% of the time somewhere around 2-4)

    I'll have to look more info about that CopyOnWriteArrayList
    Number of page #1 releases with most views & posts: (Updated: 2023)
    RS2 server section: 1
    RS2 client section: 2
    Reply With Quote  
     

  11. #7  
    Krator || Indie Dev

    Jordan Belfort's Avatar
    Join Date
    Dec 2012
    Posts
    1,051
    Thanks given
    535
    Thanks received
    485
    Rep Power
    1172
    Quote Originally Posted by Kris View Post
    As name states, it creates a new underlying arraylist every time a mutation operation is performed on the list. So if you heavily modify the contents, it might not be a good idea, especially if the collection is large.
    However the main benefit from using it is that it will never throw a concurrent modification exception, it is completely safe when it comes to that; if at all possible though, I'd avoid it; lots of unnecessary heap can cause gc to mess with your servers performance by causing spikes.
    Gotcha. Thank you.
    Attached image
    [/CENTER]
    Reply With Quote  
     

  12. #8  
    Donator

    Jason's Avatar
    Join Date
    Aug 2009
    Posts
    6,092
    Thanks given
    2,402
    Thanks received
    2,823
    Rep Power
    4550
    Another solution would be to maintain a collection of Player objects that need to be removed and added instead of removing them directly.

    Code:
    Collection<Player> remove = new HashSet<>();
    
    Collection<Player> add = new HashSet<>();
    
    void onSomeGameTick() {
        for (Player member : partyMembers) {
            // if member should be removed, add to #remove collection
            // if member should be added, add to #add collection
        }
    
        partyMembers.addAll(add);
        partyMembers.removeAll(remove);
    }
    Reply With Quote  
     

  13. Thankful users:


  14. #9  
    Respected Member


    Join Date
    Jan 2009
    Posts
    5,743
    Thanks given
    1,162
    Thanks received
    3,603
    Rep Power
    5000
    Quote Originally Posted by Jason View Post
    Another solution would be to maintain a collection of Player objects that need to be removed and added instead of removing them directly.

    Code:
    Collection<Player> remove = new HashSet<>();
    
    Collection<Player> add = new HashSet<>();
    
    void onSomeGameTick() {
        for (Player member : partyMembers) {
            // if member should be removed, add to #remove collection
            // if member should be added, add to #add collection
        }
    
        partyMembers.addAll(add);
        partyMembers.removeAll(remove);
    }
    this will still cause the original exception the op is facing, due to multiple threads.
    Reply With Quote  
     

  15. Thankful users:


  16. #10  
    Community Veteran

    mige5's Avatar
    Join Date
    Aug 2008
    Posts
    5,528
    Thanks given
    573
    Thanks received
    1,410
    Rep Power
    2114
    Quote Originally Posted by Jason View Post
    Another solution would be to maintain a collection of Player objects that need to be removed and added instead of removing them directly.

    Code:
    Collection<Player> remove = new HashSet<>();
    
    Collection<Player> add = new HashSet<>();
    
    void onSomeGameTick() {
        for (Player member : partyMembers) {
            // if member should be removed, add to #remove collection
            // if member should be added, add to #add collection
        }
    
        partyMembers.addAll(add);
        partyMembers.removeAll(remove);
    }
    I was thinking about something like this, but wouldnt it still give me the exception, if this method runs these, while some other method is looping through the list in the same time..?
    Code:
        partyMembers.addAll(add);
        partyMembers.removeAll(remove);
    Number of page #1 releases with most views & posts: (Updated: 2023)
    RS2 server section: 1
    RS2 client section: 2
    Reply With Quote  
     

Page 1 of 2 12 LastLast

Thread Information
Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)


User Tag List

Similar Threads

  1. Replies: 78
    Last Post: 07-02-2008, 04:54 PM
  2. Print Rules (Concurrency)
    By Daniel in forum Tutorials
    Replies: 1
    Last Post: 02-09-2008, 06:57 AM
  3. Train Track Modification!
    By Inside Sin in forum Videos
    Replies: 5
    Last Post: 01-12-2008, 06:11 AM
  4. Exp. Modification (1 line in client.java)
    By Dharok in forum Tutorials
    Replies: 3
    Last Post: 11-20-2007, 09:28 PM
Posting Permissions
  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •