Tuesday, May 8, 2012

How to deal with ConcurrentModificationException using iterator


Reason:
You are using ArrayList and trying to iterate thorugh this array after some change in the Collection.

This can be handled by using Synchronized on Classes like the following:


private Object pathlist;
publid void Pathlist() {
      synchronized(pathlist) {

     }
}

This will guranatee a synchronized way of handling the object pathlist, no two concurrent thread will access this in the same time but in Synchronized way.

If you are usinf Iterator somewhere in your code and get ConcurrentModificationException pay special attention to List. Use ListIterator instead of Iterator.

For example the code below will cause a ConcurrentModificationException :

public void removePathline(int pointerID) {
synchronized (this) {
Iterator<Pathline> it=pathlist.iterator();    // 1) This will throw                            
                                                                                      //ConcurrentModificationException 
//ListIterator<Pathline> it=pathlist.listIterator();   // 2) this should be used
       while(it.hasNext())
       {
          Pathline pl = (Pathline) it.next();
          synchronized ( pl ) {
          if ( pl.getPointerID() == pointerID ) {
          pathlist.remove(pl);
          }
          }
       }
}
}


The code above is removing the object while it is iterating. The iterator will check if the List has been modified and if the list has been changed, it throw a ConcurrentModificationException
In solution number 2 will solve the problem.

Java Collection classes are fail-fast which means that if the Collection will be changed while some thread is traversing over it using iterator, the iterator.next() will throw a ConcurrentModificationException.



To Avoid ConcurrentModificationException in multi-threaded environment:

1. You can convert the list to an array and then iterate on the array. This approach works well for small or medium size list but if the list is large then it will affect the performance a lot.

2.Use synchronized block. This approach is not recommended in multithreading environment if you want to use the benefits of multithreading. For the case of iterator, Synchronized approch will not solve your problem. See preferred approch below.

3. Use ConcurrentHashMap and CopyOnWriteArrayList classes if you are using JDK1.5 or higher. It is the recommended approach.







No comments:

Post a Comment