Created
October 3, 2015 23:48
-
-
Save codinko/753ae5c53c0e8eb28a10 to your computer and use it in GitHub Desktop.
ConcurrentModificationExceptionDemo in ArrayList
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.codinko; | |
import java.util.ArrayList; | |
import java.util.Iterator; | |
import java.util.List; | |
public class ConcurrentModificationExceptionDemo { | |
public static void main(String[] args) { | |
new ConcurrentModificationExceptionDemo().method1(); | |
} | |
private void method1() { | |
List<String> list = new ArrayList<String>(); | |
list.add("1"); | |
list.add("2"); | |
list.add("3"); | |
Iterator<String> iter = list.iterator(); | |
while (iter.hasNext()) { | |
/** | |
* iter.next(); -> Here, we get the concurrent modification exception after the | |
* first time list.remove(2); is invoked.And NOT when list.remove(2) is called. | |
*/ | |
String str = iter.next(); | |
System.out.println(str); | |
list.remove(2); | |
} | |
} | |
} | |
/** | |
* NOTES: | |
* | |
* /** | |
* who throws - is it the list object or the iterator or what ? Ans: Iterator throws | |
* when? Ans: Iterator throws on calling the next(). It is NOT the list object that calls when calling the remove() | |
* | |
* If you see, the concurrentModificationException is defined/thrown | |
* in private class Itr , inside public class java.util.AbstractList. | |
* | |
public E next() { | |
checkForComodification(); | |
try { | |
E next = get(cursor); | |
lastRet = cursor++; | |
return next; | |
} catch (IndexOutOfBoundsException e) { | |
checkForComodification(); | |
throw new NoSuchElementException(); | |
} | |
} | |
... | |
final void checkForComodification() { | |
if (modCount != expectedModCount) // In our example expectedModCount is 3 and modCount is 4 [three add and one remove!] | |
throw new ConcurrentModificationException(); | |
} | |
* | |
*/ | |
/** | |
* Read here: http://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html | |
* | |
* | |
* NOT only in case of MULTIPLE threads, it can also occur ONLY-IF just a SINGLE thread | |
* [this code example] modifies the original collection when the same thread | |
* is already 'iterating' over the same collection. | |
* | |
* This exception may be thrown by methods that have detected concurrent | |
* modification of an object when such modification is not permissible. | |
* | |
* For example, it is not generally permissible for one thread to modify a | |
* Collection while another thread is iterating over it. In general, the | |
* results of the iteration are undefined under these circumstances. Some | |
* Iterator implementations (including those of all the general purpose | |
* collection implementations provided by the JRE) may choose to throw this | |
* exception if this behavior is detected. | |
* | |
* Iterators that do this are known as fail-fast iterators, as they fail | |
* quickly and cleanly, rather that risking arbitrary, non-deterministic | |
* behavior at an undetermined time in the future. | |
* | |
* Note that this exception does not always indicate that an object has been | |
* concurrently modified by a different thread. If a single thread issues a | |
* sequence of method invocations that violates the contract of an object, | |
* the object may throw this exception. For example, if a thread modifies a | |
* collection directly while it is iterating over the collection with a | |
* fail-fast iterator, the iterator will throw this exception. | |
* | |
* Note that fail-fast behavior cannot be guaranteed as it is, generally | |
* speaking, impossible to make any hard guarantees in the presence of | |
* unsynchronized concurrent modification. Fail-fast operations throw | |
* ConcurrentModificationException on a best-effort basis. Therefore, it | |
* would be wrong to write a program that depended on this exception for its | |
* correctness: ConcurrentModificationException should be used only to detect | |
* bugs. | |
* | |
*/ | |
/** | |
* | |
* IMPORTANT Take-aways | |
* | |
* 1. NOT only in case of MULTIPLE threads, it can also occur ONLY-IF just a SINGLE thread | |
* [this code example] modifies the original collection when the same thread | |
* is already 'iterating' over the same collection. | |
* | |
* 2. Iterators that do this are known as fail-fast iterators | |
* | |
* 3. fail-fast behavior cannot be guaranteed as it is, generally | |
* speaking, impossible to make any hard guarantees in the presence of | |
* unsynchronized concurrent modification. | |
* Therefore, it would be wrong to write a program that depended on this exception for its | |
* correctness. | |
* | |
* 4. ConcurrentModificationException should be used only to detect bugs | |
* | |
* | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment