"Java Collection" collection iterator fast failure behavior and copyonwritearraylist

Source: Internet
Author: User
Tags concurrentmodificationexception

The following content is based on jdk1.7.0_79 source code;

What is a set iterator fast failure behavior

Take ArrayList as an example, in the case of multithreaded concurrency, if there is a thread modifying the structure of the ArrayList collection (insert, remove ...). , while another thread is iterating through the elements in the collection with an iterator, throwing an concurrentmodificationexception exception causes the iteration traversal to fail;

Arraylist.itr iterator quick Failure source code and examples

Looking at ArrayList's ITR iterator source code, you can see the private inner class ITR as ArrayList, with a Expectedmodcount member property initialized to ArrayList Modcount when the iterator object was created, That is, when the iterator object is created, it will save the set number of changes modcount to Expectedmodcount, and then each time the value is traversed, it will take ArrayList collection modification times Modcount and the Expectedmodcount comparison of the iterator , if there is a change, the collection structure after the creation of the iterator has changed, directly throw Concurrentmodificationexception exception, the following code;

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

To give a simple example that is not multithreaded, after creating the iterator, insert a piece of data toward ArrayList, and then iterate through the iterator, which throws the Concurrentmodificationexception exception:

 PackageCom.pichen.basis.col;Importjava.util.ArrayList;ImportJava.util.Iterator;Importjava.util.List; Public classMain { Public Static voidMain (string[] args) {List<Integer> list =NewArraylist<integer>();  for(inti = 0; I < 10; i++) {list.add (i); } Iterator<Integer> iterator =List.iterator (); List.add (10);  while(Iterator.hasnext ()) {iterator.next (); }    }}
java.util.ConcurrentModificationException    At Java.util.arraylist$itr.checkforcomodification (arraylist.java:859) at    Java.util.arraylist$itr.next (arraylist.java:831) at    Com.pichen.basis.col.Main.main (Main.java :)

Another multi-threading example, we create a T1 thread, loop the data into the collection, and the main thread gets the collection iterator to traverse the collection, and the following code throws the concurrentmodificationexception exception during the traversal:

 PackageCom.pichen.basis.col;Importjava.util.ArrayList;ImportJava.util.Iterator;Importjava.util.List;classThreadTestImplementsrunnable{PrivateList<integer>list;  PublicThreadTest (list<integer>list) {         This. List =list; } @Override Public voidrun () { while(true){            Try{Thread.Sleep (500); } Catch(interruptedexception e) {e.printstacktrace (); }             This. List.add (10); }    }} Public classMain { Public Static voidMain (string[] args)throwsinterruptedexception {List<Integer> list =NewArraylist<integer>();  for(inti = 0; I < 10; i++) {list.add (i); } threadtest T1=Newthreadtest (list); NewThread (T1). Start (); Iterator<Integer> iterator =List.iterator ();  while(Iterator.hasnext ()) {System.out.print (Iterator.next () )+ " "); Thread.Sleep (80); }    }}

Results Print:

java.util.ConcurrentModificationException    At Java.util.arraylist$itr.checkforcomodification (arraylist.java:859) at    java.util.arraylist$ Itr.next (Arraylist.java:831) at    Com.pichen.basis.col.Main.main (main.java:44)
Concurrentmodificationexception Exception resolution

For ArrayList collection modifications Modcount lock or replace ArrayList with Copyonwritearraylist, it is recommended to use Copyonwritearraylist

What is Copyonwritearraylist

When you look at a name, you copy the collection, or more specifically, when you modify the collection structure, copy a new collection, and then modify the structure (insert, delete) in the new collection, and then change the reference of the original collection to the new collection.

Copyonwritearraylist Supplemental Notes

Copyonwritearraylist class implements List<e>, Randomaccess, cloneable, java.io.Serializable interface

Similar to the ArrayList function, it is also a set based on dynamic array implementation;

When traversing with Copyonwritearraylist iterators, the data read is not real-time;

Each time the collection structure is modified, it is necessary to copy the data, occupy large memory;

Source view

First look at a simple example, the Add method, called the Arrays.copyof method, copies the old array to the new array, modifies the value of the new array, and modifies the reference to the collection:

     Public BooleanAdd (e e) {FinalReentrantlock lock = This. Lock;        Lock.lock (); Try{object[] elements=GetArray (); intLen =elements.length; Object[] Newelements= arrays.copyof (elements, Len + 1); Newelements[len]=e;            SetArray (newelements); return true; } finally{lock.unlock (); }    }

Then look at the implementation of the Copyonwritearraylist iterator class, some of the code below, when creating the Cowiterator iterator, you need to pass the reference of the collection's internal array to the iterator object, because when the collection is modified, the operation is for the new copy array. So the old array object inside the iterator does not change, ensuring that the data is not cluttered during the iteration (although not real-time data):

    Private Static classCowiterator<e>ImplementsListiterator<e> {        /**Snapshot of the array*/        Private Finalobject[] Snapshot; /**Index of element to is returned by subsequent call to next. */        Private intcursor; PrivateCowiterator (object[] elements,intinitialcursor) {Cursor=Initialcursor; Snapshot=elements; }        ........
Result validation

Using the example of the front throw concurrentmodificationexception, verify the use of Copyonwritearraylist,

First, create a T1 thread, loop the data into the collection, and the main thread gets the collection iterator to traverse the collection, code as follows, runs successfully, and prints out the old collection's data.

 PackageCom.pichen.basis.col;ImportJava.util.Iterator;Importjava.util.List;Importjava.util.concurrent.CopyOnWriteArrayList;classThreadTestImplementsrunnable{PrivateList<integer>list;  PublicThreadTest (list<integer>list) {         This. List =list; } @Override Public voidrun () { while(true){            Try{Thread.Sleep (500); } Catch(interruptedexception e) {e.printstacktrace (); }             This. List.add (10); }    }} Public classMain { Public Static voidMain (string[] args)throwsinterruptedexception {List<Integer> list =NewCopyonwritearraylist<integer>();  for(inti = 0; I < 10; i++) {list.add (i); } threadtest T1=Newthreadtest (list); NewThread (T1). Start (); Iterator<Integer> iterator =List.iterator ();  while(Iterator.hasnext ()) {System.out.print (Iterator.next () )+ " "); Thread.Sleep (80); }    }}

"Java Collection" collection iterator fast failure behavior and copyonwritearraylist

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.