Avoid ConcurrentModificationException land looping over Java ArrayList?

Apart from the NullPointerException in addition to ClassNotFoundException, ConcurrentModificationException is around other nightmare for Java developers. What makes this mistake tricky is the discussion concurrent, which ever mislead Java programmers that this exception is coming because multiple threads are trying to modify the collection at the same time. Then begins the hunting, they spent countless hours to expose the code which has the probability of concurrent modification. While inwards reality ConcurrentModficationException can too come upwards on the unmarried threaded environment. To give y'all an example, only loop over a listing using for loop in addition to endeavour to take i element, y'all volition acquire the ConcurrentModificatoinExcetpion? Why? because you broke the dominion of non modifying a Collection during iteration.


How does Java knows to throw ConcurrentModificationExeption? It uses a transient variable called modCount, which keeps rail of how many times a listing is modified structurally. Structural modifications are those that modify the size of the list, which may impact the progress of iteration in addition to may yield wrong results. Both Iterator in addition to ListIterator uses this champaign to respect unexpected change. Other methods of List which structurally modify List too uses this method e.g. add(), remove().


Problem: loop over an ArrayList in addition to take selected elements, but remove() is throwing "Exception inwards thread "main" java.util.ConcurrentModificationException".


Cause: The existent crusade of ConcurrentModfiicationException is inconsistent modCount. When y'all are iterating over ArrayList in addition to so Iterator's next() method perish on rail of modCount. If y'all modify the collection past times adding or removing chemical constituent in addition to so modCount volition modify in addition to it volition non fit amongst the expected modCount, therefore Iterator volition throw ConcurrentModificationException.

Here is the code snippet from hasNext() method which shows at that spot is banking concern check for modCount:

public E next() {    checkForComodification();    int i = cursor;    if (i >= size)         throw new NoSuchElementException();     Object[] elementData = ArrayList.this.elementData;     if (i >= elementData.length)         throw new ConcurrentModificationException();     cursor = i + 1;     return (E) elementData[lastRet = i];  }

Now if y'all banking concern check this checkForComodification() method, y'all volition expose what I only said:

final void checkForComodification() {     if (modCount != expectedModCount)       throw new ConcurrentModificationException(); }


Solution: Use Iterator if y'all are doing it on the unmarried threaded environment, otherwise purpose concurrent collection classes e.g. CopyOnWriteArrayList to take elements piece y'all are looping over it.


Solving ConcurrentModificationException inwards ArrayList

Here is the Java plan to demonstrate i scenario where y'all acquire the ConcurrentModificationException fifty-fifty if only i thread is modifying the ArrayList. In this example, nosotros are looping over ArrayList using advanced for loop in addition to removing selected elements, but because nosotros are using ArrayList's remove() method.


import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List;  /**  * Java Program to demonstrate how to bargain amongst  * ConcurrentModificationException.  * Unlike the refer suggests, this mistake tin flame come upwards fifty-fifty if exclusively   * i thread is modifying the collection e.g. List.   * It happens when y'all modify collection   * piece iterating over it e.g. adding novel chemical constituent or removing elements.  *   * If y'all desire to take elements piece traversing listing in addition to so   * brand certain y'all purpose Iterator's remove() method or non ArrayList's remove()  * method() to avoid ConcurrentModificationExcetpion.  *   * @author WINDOWS 8  *  */ public class ConcurrentModExceptionDemo{      public static void main(String args[]) {          List<String> listOfPhones = new ArrayList<String>(Arrays.asList(                 "iPhone 6S", "iPhone 6", "iPhone 5", "Samsung Milky Way 4", "Lumia Nokia"));                  System.out.println("list of phones: " + listOfPhones);                  // Iterating in addition to removing objects from list         // This is wrong way, volition throw ConcurrentModificationException         for(String telephone : listOfPhones){             if(phone.startsWith("iPhone")){                // listOfPhones.remove(phone); // volition throw exception             }         }                  // The Right way, iterating elements using Iterator's remove() method                  for(Iterator<String> itr = listOfPhones.iterator(); itr.hasNext();){                         String telephone = itr.next();                         if(phone.startsWith("iPhone")){                 // listOfPhones.remove(phone);  // wrong again                 itr.remove(); // right call             }         }                  System.out.println("list later removal: " + listOfPhones);      }  }  Output : listing of phones: [iPhone 6S, iPhone 6, iPhone 5, Samsung Galaxy 4, Lumia Nokia] listing later removal: [Samsung Galaxy 4, Lumia Nokia]

If y'all uncomment the commented code inwards commencement loop in addition to minute loop, y'all volition acquire the next exception:

Exception inwards thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at dto.ReverseArrayInPlace.main(ReverseArrayInPlace.java:28)

because nosotros are using ArrayList's remove() method. In the minute example, nosotros convey used remove() method of Iterator in addition to that's why nosotros are successfully able to delete selected elements from the ArrayList without ConcurrentModificationException.

Here is summary of of import points almost solving ConcurrentModificationException piece looping over ArrayList inwards Java :

NullPointerException in addition to ClassNotFoundException Avoid ConcurrentModificationException piece looping over Java ArrayList?


That's all almost how to bargain amongst ConcurrentModificationException inwards Java. The biggest affair to larn in addition to squall back is that this mistake tin flame come upwards fifty-fifty if y'all convey only i thread modifying collection e.g. removing elements piece looping over the list.

Further Learning
Java Fundamentals: Collections
From Collections to Streams inwards Java 8 Using Lambda Expressions
Grokking Algorithms past times Aditya Bhargava
Java Programming Interview Exposed past times Makham

Related troubleshooting guides
Here are around handy Java tips to solve around mutual mistake in addition to exception inwards Java:
  • How to bargain with java.lang.NoClassDefFoundError: org/apache/xmlbeans/XmlObject? (solution)
  • How to solve "could non create the Java virtual machine" mistake inwards Java? (solution)
  • Fixing java.lang.unsupportedclassversionerror unsupported major.minor version 50.0 (solution)
  • java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory mistake (solution)
  • How to solve java.lang.ClassNotFoundException: com.mysql.jdbc.Driver error? (hint)
  • How to solve java.lang.classnotfoundexception oracle.jdbc.driver.oracledriver? (solution)
  • java.lang.ClassNotFoundException : org.Springframework.Web.Context.ContextLoaderListener (solution)
  • How to cook 'javac' is non recognized every bit an internal or external command (solution)
  • How to cook Caused By: java.lang.NoClassDefFoundError: org/apache/log4j/Logger (solution)
  • How to solve java.lang.OutOfMemoryError: Java Heap Space inwards Eclipse, Tomcat? (solution)

Subscribe to receive free email updates:

0 Response to "Avoid ConcurrentModificationException land looping over Java ArrayList?"

Posting Komentar