Java.util.ConcurrentModificationException Anomaly Analysis

Source: Internet
Author: User
Tags concurrentmodificationexception

Java encountered a java.util.ConcurrentModificationException exception when manipulating container classes such as ArrayList, HashMap, TreeMap, and so on. Take ArrayList as an example, as in the following code snippet:

[Java]View Plaincopy
  1. Import java.util.ArrayList;
  2. Import Java.util.Iterator;
  3. Import java.util.List;
  4. Import java.util.concurrent.CopyOnWriteArrayList;
  5. Public class Test {
  6. public static void Main (string[] args) {
  7. list<string> strlist = new arraylist<string> ();
  8. Strlist.add ("string1");
  9. Strlist.add ("string2");
  10. Strlist.add ("string3");
  11. Strlist.add ("String4");
  12. Strlist.add ("String5");
  13. Strlist.add ("String6");
  14. //Operation mode 1:while (Iterator); Error
  15. Iterator<string> it = Strlist.iterator ();
  16. While (It.hasnext ()) {
  17. String s = it.next ();
  18. if ("string2". Equals (s)) {
  19. Strlist.remove (s);
  20. }
  21. }
  22. //Solution 1: Remove elements using Iterator's Remove method
  23. //Operation mode 1:while (Iterator): no error
  24. Iterator<string> it = Strlist.iterator ();
  25. while (It.hasnext ()) {
  26. String s = it.next ();
  27. if ("string2". Equals (s)) {
  28. It.remove ();
  29. //          }
  30. //      }
  31. //Operation mode 2:foreach (Iterator); Error
  32. for (String s:strlist) {
  33. if ("string2". Equals (s)) {
  34. Strlist.remove (s);
  35. //          }
  36. //      }
  37. //Solution 2: Do not use iterator traversal, note the consistency of indexes
  38. //Operation mode 3:for (non-iterator), no error; note Modify Index
  39. for (int i=0; i<strlist.size (); i++) {
  40. String s = strlist.get (i);
  41. if ("string2". Equals (s)) {
  42. Strlist.remove (s);
  43. Strlist.remove (i);
  44. i--;//element position changed, modify I
  45. //          }
  46. //      }
  47. //Solution 3: Create a new temporary list, stage the elements you want to delete, and finally delete them together
  48. list<string> templist = new arraylist<string> ();
  49. for (String s:strlist) {
  50. if (S.equals ("string2")) {
  51. Templist.add (s);
  52. //          }
  53. //      }
  54. View RemoveAll source, which uses iterator to traverse
  55. Strlist.removeall (templist);
  56. //Solution 4: Use thread-safe copyonwritearraylist for delete operations
  57. list<string> strlist = new copyonwritearraylist<string> ();
  58. Strlist.add ("string1");
  59. Strlist.add ("string2");
  60. Strlist.add ("String3");
  61. Strlist.add ("String4");
  62. Strlist.add ("String5");
  63. Strlist.add ("String6");
  64. Iterator<string> it = Strlist.iterator ();
  65. while (It.hasnext ()) {
  66. String s = it.next ();
  67. if (S.equals ("string2")) {
  68. Strlist.remove (s);
  69. //          }
  70. //      }
  71. }
  72. }


After executing the above code, the error is as follows:

[Plain]View Plaincopy
    1. <span style= "FONT-SIZE:14PX;" >exception in thread "main" java.util.ConcurrentModificationException
    2. At Java.util.arraylist$itr.checkforcomodification (Unknown Source)
    3. At Java.util.arraylist$itr.next (Unknown Source)
    4. At ConcurrentModificationException.Test.main (test.java:21)
    5. </span>


In the 21st line error, i.e. It.next (), the iterator gets the next element in the wrong times. Find Java.util.ArrayList Line No. 830 and see the source code of It.next () as follows:

[Java]View Plaincopy
  1. <span style="FONT-SIZE:14PX;" > @SuppressWarnings ("unchecked")
  2. Public E Next () {
  3. Checkforcomodification ();
  4. int i = cursor;
  5. if (i >= size)
  6. throw new Nosuchelementexception ();
  7. object[] Elementdata = ArrayList.  This.elementdata;
  8. if (i >= elementdata.length)
  9. throw new Concurrentmodificationexception ();
  10. cursor = i + 1;
  11. return (E) Elementdata[lastret = i];
  12. }</span>


The Checkforcomodification () method is called and the code is as follows:

[Java]View Plaincopy
    1. <span style= "FONT-SIZE:14PX;" >        final  Void checkforcomodification ()  {  
    2.              if  (modcount !=  Expectedmodcount)   
    3.                  throw new  concurrentmodificationexception ();   
    4.          }</span>  


that is, compare modcount and Expectedmodcount two for equality. Modcount is a ArrayList inherited from Abstractlist, looking at the doc document of the Modcount attribute, the Modcount indicates the number of times the list has been structurally modified (structurally modified). Structurally modified is the action that causes the number of elements in the list to change, add,addall,remove in ArrayList, Fastremove,clear, RemoveRange,   Ensurecapacity,  ensurecapacityinternal,  ensureexplicitcapacity and other methods will make Modcount plus 1, and Batchremove, Removeall,retainall and other methods are based on the number of elements removed to increase the value of Modcount (RemoveAll and Retainall are called Batchremove implementation, the specific Modcount modification algorithm needs to be studied).

The operation mode 1 and Mode 2 in the first code fragment are in the way of iterators. When using the iterator method to get the iterator object (or using Listiterator to get the Listitr object), it is actually returning a iterator interface implementation class Arraylist$itr (inherited from abstractlist$ ITR), the class is an inner class of ArrayList, which has a expectedmodcount field that, when called Arraylist$itr's Next method, Checks whether the value of the modcount is equal to the value of expectedmodcount (in fact, it will be checked when calling next, remove, previous, set, add, etc.), Java.util.ConcurrentModificationException exceptions are thrown when they are not equal.

Why is this exception thrown? From the code can see the call 6 times the Add method, then the value of Modcount is 6, when using the iterator method to get the iterator object Modcount value is assigned to Expectedmodcount, At the beginning, expectedmodcount and modcount are equal when iterating to the second element (index=1) "string2", because the IF condition is true, and then the Remove method is called, The Modcount value is added 1 when the Remove method is called, at which point the value of Modcount is 7, and the value of Expectedmodcount is not changed when the arraylist$ is called again. The next method of ITR detects that Modecount and expectedmodcount are not equal and throws an exception.

What if the If statement is written as if (S.equals ("String5")) without throwing the exception? Arraylist$itr also has a field named cursor that points to the index of the element to be manipulated at iteration, with an initial value of 0, and a value of 1 for each call to the next method, noting that the element is first removed from the collection plus 1. When judging "string5", note is the second-to-last element, these cursor value is 5, remove the element "String5", the list of size 5, when the Hasnext method called Arraylist$itr to determine if there is no next element, The judgment is based on whether the value of the cursor is equal to the size, the difference is the next element, and when the two values are exactly equal, there is no next method to execute, and no exception is thrown, so the exception that is not thrown when the second-to-last element is deleted.

There are four solutions, just look at the first piece of code.

Java.util.ConcurrentModificationException Anomaly Analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.