Sunday, November 24, 2019

Avoid Concurrentmodificationexception Piece Looping Over Coffee Arraylist?

Apart from the NullPointerException in addition to ClassNotFoundException, ConcurrentModificationException is to a greater extent than or less other nightmare for Java developers. What makes this mistake tricky is the give-and-take 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 unwrap the code which has the probability of concurrent modification. While inwards reality ConcurrentModficationException can likewise come upwardly on the unmarried threaded environment. To laissez passer y'all an example, simply loop over a listing using for loop in addition to endeavour to withdraw 1 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 rails of how many times a listing is modified structurally. Structural modifications are those that alter the size of the list, which may deport on the progress of iteration in addition to may yield wrong results. Both Iterator in addition to ListIterator uses this plain to abide by unexpected change. Other methods of List which structurally modify List likewise uses this method e.g. add(), remove().


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



Cause: The existent elbow grease of ConcurrentModfiicationException is inconsistent modCount. When y'all are iterating over ArrayList in addition to then Iterator's next() method proceed rails of modCount. If y'all modify the collection past times adding or removing chemical constituent in addition to then modCount volition alter in addition to it volition non agree amongst the expected modCount, so Iterator volition throw ConcurrentModificationException.

Here is the code snippet from hasNext() method which shows at that topographic point is cheque 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 cheque this checkForComodification() method, y'all volition unwrap what I simply 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 piece of occupation concurrent collection classes e.g. CopyOnWriteArrayList to withdraw elements piece y'all are looping over it.


Solving ConcurrentModificationException inwards ArrayList

Here is the Java plan to demonstrate 1 scenario where y'all acquire the ConcurrentModificationException fifty-fifty if simply 1 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 come upwardly fifty-fifty if alone   * 1 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 withdraw elements piece traversing listing in addition to then   * brand certain y'all piece of occupation 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 showtime 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 accept 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 most solving ConcurrentModificationException piece looping over ArrayList inwards Java :

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


That's all most how to bargain amongst ConcurrentModificationException inwards Java. The biggest affair to larn in addition to recollect is that this mistake tin come upwardly fifty-fifty if y'all accept simply 1 thread modifying collection e.g. removing elements piece looping over the list.

Further Learning
Java In-Depth: Become a Complete Java Engineer
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 create 'javac' is non recognized equally an internal or external command (solution)
  • How to create Caused By: java.lang.NoClassDefFoundError: org/apache/log4j/Logger (solution)
  • How to solve java.lang.OutOfMemoryError: Java Heap Space inwards Eclipse, Tomcat? (solution)

  • No comments:

    Post a Comment