Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there a ConcurrentModificationException even when list is synchronized?

I have Android multi-threading application.

There is some probability that two or more triggers might run the same part of code.

I have a list of objects.

I made it to be synchronized by Collections.synchronizedList

private List<WmGroupItemSample> mGroupItemSampleList;

mGroupItemSampleList = new ArrayList<WmGroupItemSample>();
mGroupItemSampleList = Collections.synchronizedList(mGroupItemSampleList);

However sometimes I get Exception on line:

Collections.sort(mGroupItemSampleList, new GroupItemSampleComparator());

java.util.ConcurrentModificationException
       at java.util.AbstractList$SimpleListIterator.next(AbstractList.java:62)
       at java.util.Collections.sort(Collections.java:1895)
  • Is this flow legal?
  • do I need create the copy and run sort on copy?
  • why Collections.synchronizedList doesn't prevent this Exception?

[EDIT]

GroupItemSampleComparator

public class GroupItemSampleComparator implements java.util.Comparator<WmGroupItemSample> {

    public GroupItemSampleComparator() {
        super();        
    }

    public int compare(WmGroupItemSample s1, WmGroupItemSample s2) {
       return ( (s2.getStartDate() - s1.getStartDate()) > 0 ) ? (-1) : (1);
    }
}

Thanks,

like image 650
snaggs Avatar asked Aug 04 '14 07:08

snaggs


People also ask

How can I avoid ConcurrentModificationException while iterating a list?

To Avoid ConcurrentModificationException in single-threaded environment. You can use the iterator remove() function to remove the object from underlying collection object. But in this case, you can remove the same object and not any other object from the list.

What causes ConcurrentModificationException?

What Causes ConcurrentModificationException. The ConcurrentModificationException generally occurs when working with Java Collections. The Collection classes in Java are very fail-fast and if they are attempted to be modified while a thread is iterating over it, a ConcurrentModificationException is thrown.

How do I fix ConcurrentModificationException in Java?

How do you fix Java's ConcurrentModificationException? There are two basic approaches: Do not make any changes to a collection while an Iterator loops through it. If you can't stop the underlying collection from being modified during iteration, create a clone of the target data structure and iterate through the clone.

Does synchronized HashMap throws ConcurrentModificationException?

Synchronized HashMap allows one null key and any number of null values. Iterators returned by Hashtable are fail-safe in nature. i.e they don't throw ConcurrentModificationException if the map is modified after the creation of the iterator.


1 Answers

Collections.synchronizedList(list) returns a synchronized list which means that the methods of the list will be synchronizd (only one of them can be running at the same time).

This however does not mean you can't call a method of the list while someone else (or maybe you) is iterating over the list using its iterator (iterators returned by iterator() are not synchronized). synchronizedList() does not protect you from getting a ConcurrentModificationException if someone is iterating over the list and it is modified in any other way than the iterator's methods.

Edit:

Also your GroupItemSampleComparator is bad, it must return 0 if the passed 2 objects are considered to be equal by their equals() method. Try this (assuming getStartDate() returns long):

public int compare(WmGroupItemSample s1, WmGroupItemSample s2) {
    long diff = s2.getStartDate() - s1.getStartDate();
    return diff > 0 ? -1 : diff < 0 ? 1 : 0;
}
like image 86
icza Avatar answered Sep 28 '22 01:09

icza