A quick fail (fail-fast) mechanism in the Java Collection framework

Source: Internet
Author: User
Tags concurrentmodificationexception

First, the conclusion: when using for traversal of a collection object, if the contents of the collection object are modified (added, deleted) during traversal, Concurrentmodificationexception is thrown. Iterating through the modifications in a single thread without an error. In the multi-threaded environment will be error.

?? Principle: The iterator accesses the contents of the collection directly during traversal, and uses a Modcount variable during traversal. When a collection is traversed, the value of Modcount is changed if the content changes. Each time the iterator uses Hashnext ()/next () to traverse the next element, it detects whether the Modcount variable is a expectedmodcount value, and then returns the traversal, otherwise throws an exception and terminates the traversal.
?? Here the exception is thrown condition is detected modcount!=expectedmodcount this condition. The exception is not thrown if the change of the Modcount value is exactly set to the Expectedmodcount value when the collection changes. Therefore, it is not possible to rely on the exception to be thrown and to program concurrent operations, which is only recommended for detecting concurrent modification bugs.

Let's check if the update data with the enhanced for loop in a single thread will be an error:

import java.util.*;publicstaticvoidmain(String[] args) {    new ArrayList<>();    for(int i=0;i<10;i++) {        list.add(i);    }    for(int n:list){        if(n==6){            list.set16);        }    }    System.out.println(list.toString());}

Output is [0, 1, 2, 3, 4, 5, 16, 7, 8, 9]

What if we delete the parameters in the traversal?

publicstaticvoidmain(String[] args) {    new ArrayList<>();    for(int i=0;i<10;i++) {        list.add(i);    }    for(int n:list){        if(n==6){            list.remove(n);        }    }    System.out.println(list.toString());}
->Exception in thread "main" java.util.ConcurrentModificationException

What is this for? Let's look at the source code for set:

publicset(int index, E element) {   rangeCheck(index);   elementData(index);   elementData[index] = element;   return oldValue;}

We found that when the set operation was performed, the Modcount did not increment, so there was no error.

What if I traverse remove with an iterator?

publicstaticvoidmain(String[] args) {    new ArrayList<>();    for(int i=0;i<10;i++) {        list.add(i);    }    Iterator<Integer> it = list.iterator();    while (it.hasNext()) {        if (it.next6) {            it.remove();        }    }    System.out.println(list.toString());}
->[0, 1, 2, 3, 4, 5, 7, 8, 9]

This is because:

  • An iterator is implemented as an inner class of the current collection and maintains a reference to the current collection when the iterator is created;
  • The set internally maintains an int variable modcount, which is used to record the number of times the collection has been modified, such as Add,remove, which increments the field;
  • Modcount This parameter records the number of times a list is resized and throws an exception if the Modcount change does not match expectations.
  • The field inside the iterator also maintains the number of modifications to the current collection, which is initialized to the Modcount value of the collection when the iterator is created
  • When each iteration, the iterator compares the values of the fields maintained by the iterator with the Modcount, and throws the concurrentmodifiedexception exception if it is not equal;
  • Of course, if you call the Remove method with an iterator, the number of modifications that the collection and the iterator maintains will be incremented to maintain the consistency of the two States.

As shown in the following ArrayList inherited abstractlist source code:

  • Defines the Modcount
protectedtransientint0;

ArrayList Source:

 Public void Remove() {if(Lastret <0)Throw NewIllegalStateException ();checkforcomodification();Try{ArrayList. This.Remove(Lastret);        cursor = Lastret; Lastret =-1;    Expectedmodcount = Modcount; }Catch(Indexoutofboundsexception ex) {Throw NewConcurrentmodificationexception (); }} PublicERemove(intIndex) {Rangecheck(index);    modcount++; E OldValue =Elementdata(index);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    returnOldValue;}Private void Rangecheck(intIndex) {if(Index >= size)Throw NewIndexoutofboundsexception (outofboundsmsg(index));}

You can see that the variable modcount is self-increasing when the remove operation

?? The collection classes under the Ps:java.util package are fast-failing and cannot be modified in parallel under multiple threads (iterative process).

Security Failure (Fail-Safe)

?? A collection container using the security failure mechanism, which is not accessed directly on the collection content, but first copies the original collection content and iterates over the copied collection.

?? Principle: Since iteration is a copy of the original collection, so the changes made to the original collection during traversal cannot be detected by iterators, so concurrent modification Exception is not triggered.
?? Cons: The advantage of copy-based content is to avoid concurrent modification Exception, but again, iterators do not have access to the modified content, i.e., the iterator iterates through the collection copies that were taken at the moment of the traversal, The modification iterator that occurs during the traversal of the original collection is not known.
?? the containers under the Ps:java.util.concurrent package are security failures that can be used concurrently in multiple threads and concurrently modified.

A quick fail (fail-fast) mechanism in the Java Collection framework

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.