Concurrentmodificationexception of the Java list container

Source: Internet
Author: User
Tags goto concurrentmodificationexception

Many of the containers in Java are modified while they are being traversed, and the elements are concurrentmodificationexception, including multithreading and single-threaded scenarios. Multithreading is the case, the single-threaded occurrence of this exception is generally a traversal (ForEach) in the process of modification caused the state inconsistency in the list, in order to prevent inconsistencies caused unpredictable consequences, so throw an exception. In ArrayList, for example, an internal state check is performed for each operation, as shown in the following code:

Final void checkforcomodification () {         if (modcount! = expectedmodcount         )throw  New  concurrentmodificationexception ();
}

When these two values are different, it means that the previous operation has an exception. Where modcount is defined in abstractlist to indicate the number of times the list has been modified. Expectedmodcount is defined in the iterator parent class, and the default value equals Modcount used to represent the desired number of modifications.

But sometimes there is a need to iterate over the changes, such as removing unwanted entries during traversal. This requirement can be fulfilled in a single thread and can be used in the following two ways:

     Public  voidModifyiterator () {Iterator<String> iterator =List.iterator ();  while(Iterator.hasnext ()) {String str=Iterator.next (); if(Str.equals ("") ) Iterator.remove (); }    }         Public  voidModifybyindex () { for(intI=0;i<list.size (); i++) {String str=List.get (i)if(Str.equals ("") ) List.remove (i); }    }                      

Typically, iterator is used, which is not commonly used, and because the element moves after an element is deleted by ArrayList, it will cause an index change and will have an impact on traversal. However, if you use foreach, you will get an error (which is also easy for beginners to make):

 Public  void Modifyforeach () {        for(String str:list) {            list.remove (str);        }    }

If you use the above code, you will get an error. Why would this form be an error? First, take a look at the machine code for the two functions:

  Public voidModifyiterator (); Code:0: Aload_01:getfield #17//Field list:ljava/util/list;4:invokeinterface #34, 1//Interfacemethod Java/util/list.iterator: () Ljava/util/iterator;9: Astore_110:Goto19 13: Aload_114:invokeinterface #56, 1//Interfacemethod Java/util/iterator.remove: () V19: Aload_120:invokeinterface #49, 1//Interfacemethod Java/util/iterator.hasnext: () Z25:ifne 13 28:return} Public voidModifyforeach (); Code:0: Aload_01:getfield #17//Field list:ljava/util/list;4:invokeinterface #34, 1//Interfacemethod Java/util/list.iterator: () Ljava/util/iterator;9: astore_210:Goto34 13: Aload_214:invokeinterface #38, 1//Interfacemethod Java/util/iterator.next: () Ljava/lang/object;19:checkcast #44//class Java/lang/string22: Astore_123: Aload_024:getfield #17//Field list:ljava/util/list;27: Aload_128:invokeinterface #46, 2//interfacemethod java/util/list.remove: (ljava/lang/object;) Z33: Pop34: Aload_235:invokeinterface #49, 1//Interfacemethod Java/util/iterator.hasnext: () Z40:ifne 13 43:return

You can see that the traversal process for foreach also uses iterator. But why does the latter make an error? The reason is simple, foreach gets iterator at the beginning, the deletion process does not update the iterator state, so the final state is inconsistent. First, take a look at iterator's delete code:

  Public BooleanRemove (Object o) {if(O = =NULL) {             for(intindex = 0; index < size; index++)                if(Elementdata[index] = =NULL) {fastremove (index); return true; }        } Else {             for(intindex = 0; index < size; index++)                if(O.equals (Elementdata[index])) {fastremove (index); return true; }        }        return false; }    Private voidFastremove (intindex) {Modcount++; intnummoved = size-index-1; if(nummoved > 0) system.arraycopy (elementdata, index+1, Elementdata, Index, nummoved); elementdata[--size] =NULL;//clear to let GC do it work}

The Fastremove method modifies the Modcount, but since iterator has gone back, the expectedmodcount in it has not been updated, resulting in inconsistencies between the two.

Summary: Multi-threaded simultaneous modification of the list or single-threaded using the foreach traversal to modify the list process, many lists will report concurrentmodificationexception errors. This error is due to Expectedmodcount in iterator and Modcount inconsistency in list. Because foreach also uses iterator, but the modification uses a list-related method, iterator does not follow the update. therefore, in the case of multithreading, any operation needs to be synchronized to avoid inconsistent data in the list, and single-threaded traversal modification must use iterator.

Concurrentmodificationexception of the Java list container

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.