ConcurrentModificationException in LinkedList

15,677

Solution 1

The ConcurrentModificationException is usually thrown when iterating through the list and in the same time usually another thread or even the same loop tries to modify (add / remove) the contents of the list.

Solution 2

Using a synchronizedList or a synchronized list still has to be synchronised externally when iterating over it.

If you use ConcurrentLinkedQueue you don't have these issues.

Queue<Task> tasks = new ConcurrentLinkedQueue<Task>();
tasks.add(task); // thread safe
tasks.remove(task2); // thread safe

for(Task t: tasks) // can iterate without a CME.

Note: if you are using a queue with another thread I suggest you use an ExecutorService as this combines a Queue with a ThreadPool and make working with "background" thread much easier.

Solution 3

why not use LinkedBlockingQueue? http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/LinkedBlockingQueue.html

BTW, it's not neceserally have to do with synchronization. a code like this:

for(Value v : valuesList){
    valueslist.add(new Value());
}

would cause this exception as well. check your code for possible modifications of the list when it's being iterated over.

Solution 4

Java collections are fail-fast, that means that all existing Iterators become invalid the moment the underlying collection is modified - synchronizing the modification does not stop the list from invalidating all iterators.

As a workaround you can create a copy of the list to iterate over or postpone modifications until the iteration is finished. To remove entries you can also use the iterator.remove() method which keeps the iterator itself valid.

Solution 5

This happens when you iterate over the list and add elements to it in the body of the loop. You can remove elements safely when you use the remove() method of the iterator but not by calling any of the remove() methods of the list itself.

The solution is to copy the list before you iterate over it:

List<T> copy = new ArrayList<T>( list );
for( T e : copy ) {
    ... you can now modify "list" safely ...
}
Share:
15,677
Sameera Kumarasingha
Author by

Sameera Kumarasingha

Updated on June 15, 2022

Comments

  • Sameera Kumarasingha
    Sameera Kumarasingha almost 2 years

    I am trying to designing a software that convert a flowchart into java or any other code. However I repeatedly getting the ConcurrentModificationException.. But I can't use a boolean to prevent concurrentModification, because access to the linked list happens in various places.

    So as a solution I created the below adapter class. However it also throws the same exception from next method. Are there any other solution or if can, plz let me know how to modify my codes...

    thank you very much...

    import java.util.Iterator;
    import java.util.LinkedList;
    
    public class LinkedListAdapter<T> extends LinkedList<T>{
    
    @Override
    public boolean add(T t){
    
        boolean b;
    
        synchronized(this){
            b = super.add(t);
        }
    
        return b;
    }
    
    @Override
    public T remove(){
    
        T t;
    
        synchronized(this){
            t = super.remove();
        }
    
        return t;
    }
    
    @Override
    public Iterator<T> iterator(){
    
        final LinkedListAdapter<T> adap = this;
    
        return 
            new Iterator<T>(){
    
            private Iterator<T> iter;
    
            {
                synchronized(adap){
                    iter = LinkedListAdapter.this.getIterator();
                }
            }
    
            @Override
            public boolean hasNext() {
    
                boolean b;
    
                synchronized(adap){
                    b = iter.hasNext();
                }
    
                return b;
            }
    
            @Override
            public T next() {
    
                T t;
    
                synchronized(adap){
                    t = iter.next();
                }
    
                return t;
            }
    
            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
    }
    
    protected Iterator<T> getIterator() {
    
        Iterator<T> iter;
    
        synchronized(this){
            iter = super.iterator();
        }
    
        return iter;
    }
    }
    
    • josefx
      josefx over 11 years
      @SLaks "it will work once you fix it" has to be the most helpful comment on SO ever.
    • SLaks
      SLaks over 11 years
      @josefx: My point is that his question is addressing the problem completely backwards.
    • Sameera Kumarasingha
      Sameera Kumarasingha over 11 years
      Yes. That's correct. When designed the software I didn't expect any multithreading problems, because I used a single thread. However multithreading problems arise unexpectedly when using paintComponent. Then as a solution, I tried to use an adapter. Thank you very much
  • Sameera Kumarasingha
    Sameera Kumarasingha over 11 years
    Yes, in my program two threads are iterating at the same time, however coding are in different places. Because that I tried to make an adapter. Thank you very much....
  • Colateral
    Colateral over 7 years
    Unfortunately this is not working. I tried to modify the list from 2 timers with synchronized(list) on both.
  • Aaron Franke
    Aaron Franke about 6 years
    How can I search for items in the list to remove and remove them, then?
  • jfajunior
    jfajunior over 5 years
    This is the cleanest solution.