Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java : ConcurrentModificationException while iterating over list [duplicate]

When I execute the following code, I get ConcurrentModificationException

 Collection<String> myCollection = Collections.synchronizedList(new ArrayList<String>(10));
    myCollection.add("123");
    myCollection.add("456");
    myCollection.add("789");
    for (Iterator it = myCollection.iterator(); it.hasNext();) {
        String myObject = (String)it.next();
        System.out.println(myObject);
        myCollection.remove(myObject); 
        //it.remove();
    }

Why am I getting the exception, even though I am using Collections.synchronizedList?

When I change myCollection to

  ConcurrentLinkedQueue<String> myCollection = new ConcurrentLinkedQueue<String>();

I don't get that exception.

How is ConcurrentLinkedQueue in java.util.concurrent different from Collections.synchronizedList ?

like image 307
Vinoth Kumar C M Avatar asked Jul 06 '11 12:07

Vinoth Kumar C M


2 Answers

A synchronized List will does not provide a new implementation of Iterator. It will use the implementation of the synchronized list. The implementation of iterator() is:

public Iterator<E> iterator() {
   return c.iterator(); // Must be manually synched by user! 
}

From ArrayList:

The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException

From ConcurrentLinkedQueue#iterator:

Returns an iterator over the elements in this queue in proper sequence. The returned iterator is a "weakly consistent" iterator that will never throw ConcurrentModificationException, and guarantees to traverse elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to construction.

The iterators returned by the two collections are different by design.

like image 168
Andreas Dolk Avatar answered Sep 28 '22 17:09

Andreas Dolk


don't do

myCollection.remove(myObject); 

do

it.remove();

There is no need for synchronization or concurrent collection

like image 36
unbeli Avatar answered Sep 28 '22 16:09

unbeli