Analysis of the cause of abnormal List quote ConcurrentModificationException whe

Recommended for you: Get network issues from WhatsUp Gold. Not end users.

  When you use Iterator to iterate through the List if you modify the List object, it will offer java.util.ConcurrentModificationException exception, see below an example:

 1 package com.others;
 2 
 3 import java.util.ArrayList;
 4 import java.util.Iterator;
 5 import java.util.List;
 6 import java.util.concurrent.CopyOnWriteArrayList;
 7 
 8 public class ArrayListTest {
 9 
10     public static void main(String[] args) {
11         List<String> list = new ArrayList<String>();
12         //CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();
13         list.add("a");
14         list.add("b");
15         list.add("c");
16         list.add("d");
17         list.add("e");
18         Iterator iterator = list.iterator();
19         while(iterator.hasNext()){
20             String str = (String) iterator.next();
21             if(str.equals("c")){
22                 list.remove(str);
23             }else{
24                 System.out.println(str);
25             }
26         }
27     }
28 
29 }

  Results for the:

a
b
Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
    at java.util.ArrayList$Itr.next(ArrayList.java:791)
    at com.others.ArrayListTest.main(ArrayListTest.java:20)

  When you call the list iterator () method, returns an object that implements the Iterator interface (Itr):

1 public Iterator<E> iterator() {
2         return new Itr();
3     }

  We look at the Itr class:

 1 private class Itr implements Iterator<E> {
 2         int cursor;       // index of next element to return
 3         int lastRet = -1; // index of last element returned; -1 if no such
 4         int expectedModCount = modCount; //The newly created object when the List modCount iteration
 5 
 6         public boolean hasNext() {
 7             return cursor != size;
 8         }
 9 
10         @SuppressWarnings("unchecked")
11         public E next() {
12             checkForComodification(); //Every one call to next () function will call the checkForComodification method to determine a
13             int i = cursor;
14             if (i >= size)
15                 throw new NoSuchElementException();
16             Object[] elementData = ArrayList.this.elementData;
17             if (i >= elementData.length)
18                 throw new ConcurrentModificationException();
19             cursor = i + 1;
20             return (E) elementData[lastRet = i];
21         }
22 
23         public void remove() {
24             if (lastRet <0)
25                 throw new IllegalStateException();
26             checkForComodification();
27 
28             try {
29                 ArrayList.this.remove(lastRet);
30                 cursor = lastRet;
31                 lastRet = -1;
32                 expectedModCount = modCount;
33             } catch (IndexOutOfBoundsException ex) {
34                 throw new ConcurrentModificationException();
35             }
36         }
37         //This method is used to determine the time to create the iterative object List modCount and now List modCount is the same, not the same thing at ConcurrentModificationException anomaly
38         final void checkForComodification() {
39             if (modCount != expectedModCount)
40                 throw new ConcurrentModificationException();
41         }
42     }

  The List object has a member variable modCount, which represents the number of times the List object is modified, each of the List object to modify a, modCount will add 1

  A member variable expectedModCount Itr class, its value is the time to create a Itr object List modCount value. Use this variable to test in the iterative process of List if the object has been modified, if has been modified java.util.ConcurrentModificationException is thrown. In each Itr object called the next () method when they call checkForComodification () method is a test, checkForComodification()Do the work method is to compare expectedModCount  and modCount values are equal;, If not equal., We think there are other object is operating on the current List, That will throw a ConcurrentModificationException exception.

  We'll analyze the above example, when the example program execution to the 22 row, the list object inside the “ C "to delete the list object, and the modCount value plus 1, but the Itr object of the expectedModCount has not changed, they certainly are not equal. And so again execute next () method when the call checkForComodification () method, and it throws an exception.

  The above example we will look a little change: will the 21 to if (str.equals ("d")) {&rdquo D ", delete the elements. Results are as follows:

a

b

c

  But without exception, but “ e "did not come out, this is why? The reason is very simple, we see Itr hashNext () method:

1 public boolean hasNext() {
2             return cursor != size;
3         }

  It is to determine whether there is no iteration of the object through the cursor and List object Itr object size, When the traversal of “ D "cursor=4, Delete ” D "when, The List object's size will decrease 1, Size first 5, Later changed to 4, When cursor and size are equal, hasNext()Method returns the false, That the traversal over, So when did not go in implementation of next (deleted) method., There is no exception., Of course, "e" has not lost.

  To avoid this anomaly, we can use CopyOnWriteArrayList instead of ArrayList, CopyOnWriteArrayList supports concurrent access, so simultaneous iteration and modification is no problem.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Posted by Troy at November 14, 2013 - 3:16 AM