Java Traversal list Concurrentmodificationexception Exception parsing __java

Source: Internet
Author: User
Tags object object concurrentmodificationexception

One, single thread
1. Examples of anomalies
As long as the exception is thrown, you can be sure that the code must have the wrong place. Let's take a look at all the situations where the concurrentmodificationexception exception appears, following the ArrayList remove operation for example:

Data collection to use:

     List myList = new ArrayList ();

           Mylist.add ("1");
           Mylist.add ("2");
           Mylist.add ("3");
           Mylist.add ("4");
           Mylist.add ("5");

Exceptions occur in the following three scenarios:

     Iterator it = Mylist.iterator ();
            while (It.hasnext ()) {
                String value = It.next ();
                 if (Value.equals ("3")) {
                     mylist.remove (value);  Error
                }
           } for

            (iterator it = Mylist.iterator (); It.hasnext ();) {
                String value = It.next ();
                 if (Value.equals ("3")) {
                     mylist.remove (value);  Error
                }
           } for


            (String value:mylist) {
                System. Out.println ("List value:" + value);
                 if (Value.equals ("3")) {
                     mylist.remove (value);  Error
                }
           }   

The exception information is as follows:

Exception in thread ' main ' java.util.ConcurrentModificationException at
java.util.abstractlist$ Itr.checkforcomodification (Unknown source) at
Java.util.abstractlist$itr.next (Unknown source)
Root cause
All of the above 3 types of anomalies have a common feature, are traversed using iterator, and are all through the Arraylist.remove (Object) to delete operations.
To find the root cause, look directly at the ArrayList source to see why the exception occurred:
public class ArrayList extends Abstractlist implements Cloneable, Serializable, randomaccess {@Overrid
        E public Boolean remove (Object object) {object[] a = array;
        int s = size;
                    if (object!= null) {for (int i = 0; i < s; i++) {if (Object.Equals (a[i))) {
                    System.arraycopy (A, i + 1, a, I,--s-i);  A[s] = null;
                    Prevent memory leak size = s;  modcount++;
                As long as the deletion success is cumulative return true;
                    }} else {for (int i = 0; i < s; i++) {if (a[i] = = null) {
                    System.arraycopy (A, i + 1, a, I,--s-i);  A[s] = null;
                    Prevent memory leak size = s;  modcount++;
                As long as the deletion success is cumulative return true;
    }} return false;   


    }@Override Public iterator iterator () {return new arraylistiterator (); Private class Arraylistiterator implements iterator {...//total number of global modifications saved to the current class/** T

        He expected Modcount value */private int expectedmodcount = Modcount;
            @SuppressWarnings ("unchecked") public E Next () {ArrayList ourlist = arraylist.this;
               int rem = remaining; If the value is not the same when created, throw an exception if (Ourlist.modcount!= expectedmodcount) {throw new Concurrentmodificatio
            Nexception ();
            } if (rem = 0) {throw new nosuchelementexception ();
            } remaining = Rem-1;
        Return (E) Ourlist.array[removalindex = Ourlist.size-rem];
}   

          ......
     }    }

List, Set, Map can be traversed through the iterator, here is only through the list example, in the use of other sets of the traversal of the additions and deletions to be aware of the trigger Concurrentmodificationexception exception.

Solution
Listed above are several cases of problems, but also analyzed the root cause of the problem, now to summarize what is right, if you avoid the traversal of the operation does not appear concurrentmodificationexception exception.

    1 Use the Remove method provided by iterator to remove the current element
     for (Iterator it = Mylist.iterator (); It.hasnext ();) {
                String value = It.next ();
                 if (Value.equals ("3")) {
                     it.remove ();  OK
                }
           System. Out.println ("List Value:" + mylist.tostring ());
        2 Build a collection, record the elements that need to be deleted, and then unify the deletion             
     List templist = new ArrayList ();
            for (String value:mylist) {
                 if (value.equals ("3")) {
                     Templist.add (value);
                }
           }
        Can view the RemoveAll source code, which uses iterator to traverse
     Mylist.removeall (templist);
           System. Out.println ("List Value:" + mylist.tostring ());  
         3. Using thread-safe copyonwritearraylist for delete operations
    List myList = new Copyonwritearraylist ();
           Mylist.add ("1");
           Mylist.add ("2");
           Mylist.add ("3");
           Mylist.add ("4");
           Mylist.add ("5");

           Iterator it = Mylist.iterator ();

            while (It.hasnext ()) {
                String value = It.next ();
                 if (Value.equals ("3")) {
                     Mylist.remove ("4");
                     Mylist.add ("6");
                     Mylist.add ("7");
                }
           System. Out.println ("List Value:" + mylist.tostring ());
        4. Do not use iterator to traverse, you need to note that the index is normal
    for (int i = 0; i < mylist.size (); i++) {
                String value = Mylist.get (i);
                System. Out.println ("List value:" + value);
                 if (Value.equals ("3")) {
                     mylist.remove (value);  OK
                     i--;//Because the position has changed, you must modify the position of I}
           System. Out.println ("List Value:" + mylist.tostring ());

The output results are: List value:[1, 2, 4, 5], and no exception occurs.
The above 4 solutions are completely free to test in a single thread, but if they are in multiple threads.

Second, multithreading
1. Examples of synchronization anomalies
The above for the concurrentmodificationexception exception in a single threaded case to propose 4 solutions, could have been very ha-skin wash and sleep, but if it involves multi-threaded environment may not be so optimistic.
In the following example, two child threads are opened, one is traversed, and the other is conditionally deleted:

     Final List myList = Createtestdata (); New Thread (New Runnable () {@Override public void run () {for String s

                         Tring:mylist) {System.out.println ("traversal Set value =" + string);
                         try {thread.sleep (100);
                         catch (Interruptedexception e) {e.printstacktrace ();

          }}}). Start (); New Thread (New Runnable () {@Override public void run () {for iterator I t = Mylist.iterator (); It.hasnext ();)

                     {String value = It.next ();

                     System.out.println ("delete element value =" + value);
                     if (Value.equals ("3")) {it.remove ();
                              } try {Thread.Sleep (100);
                         catch (Interruptedexception e) {e.printstacktrace (); }}}). Start ();

Output results:
Traversal Collection value = 1
Delete element value = 1
Traversal Collection value = 2
Delete element value = 2
Traversal Collection value = 3
Delete element value = 3

Exception in thread "Thread-0" Delete element value = 4
java.util.ConcurrentModificationException
at Java.util.abstractlist$itr.checkforcomodification (Unknown Source) at
Java.util.abstractlist$itr.next (Unknown Source) at
list. Concurrentmodificationexceptionstudy$1.run (concurrentmodificationexceptionstudy.java:42) at
Java.lang.Thread.run (Unknown Source)
Deletes element value = 5

Conclusion:
The above example uses It.remove () for a 1th solution that uses only a single thread traversal to delete in a multi-threaded situation, but the test learns that 1, 2, and 3 of the 4 solutions are still problematic.
And then look at Javadoc's description of the java.util.ConcurrentModificationException exception:
This exception is thrown when the method detects concurrent modifications to the object, but does not allow this modification.
This means that the above methods are fine when executed by the same thread, but exceptions can still occur in asynchronous situations.

Try the Scenario
(1) Add synchronized or use collections.synchronizedlist in all traversal additions and deletions, although it is not recommended to solve the problem, because the synchronization lock caused by addition or deletion may block traversal operation.
(2) Recommend the use of Concurrenthashmap or copyonwritearraylist.

Copyonwritearraylist Matters needing attention
(1) Copyonwritearraylist cannot be deleted using Iterator.remove ().
(2) Copyonwritearraylist using iterator and using List.remove (Object), the following exception occurs:

java.lang.UnsupportedOperationException:Unsupported operation remove at
Java.util.concurrent.copyonwritearraylist$listiteratorimpl.remove (copyonwritearraylist.java:804)
Solution
There are 4 solutions in a single-threaded scenario, but it is found that there is only a 4th scenario in multi-threaded situations where the problem does not occur in multi-threaded situations.
     List myList = new Copyonwritearraylist ();
           Mylist.add ("1");
           Mylist.add ("2");
           Mylist.add ("3");
           Mylist.add ("4");

          Mylist.add ("5"); New Thread (New Runnable () {@Override public void run () {for String s

                         Tring:mylist) {System.out.println ("traversal Set value =" + string);
                         try {thread.sleep (100);
                         catch (Interruptedexception e) {e.printstacktrace ();

          }}}). Start ();  New Thread (New Runnable () {@Override public void run () {for (int i = 0; I < mylist.size ();

                         i++) {String value = Mylist.get (i);

             System.out.println ("delete element value =" + value);        if (Value.equals ("3")) {Mylist.remove (value); i--; Note} try {Thread.s
                         Leep (100);
                         catch (Interruptedexception e) {e.printstacktrace (); }}}). Start ();

Output results:
Delete element value = 1
Traversal Collection value = 1
Delete element value = 2
Traversal Collection value = 2
Delete element value = 3
Traversal Collection value = 3
Delete element value = 4
Traversal Collection value = 4
Delete element value = 5
Traversal Collection value = 5

OK, it's done.

RELATED LINKS

1 Java concurrentmodificationexception Exception analysis and solution

2 The reason of throwing concurrentmodificationexception and the solution

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.