I understood this concept from some tutorial and as long as i know when one thread is iterating list ,other thread is allowed to modify underlying list and we wont get ConcurrentModificationException(CME) but in case of ArrayList we will get CME.
but in the following program there is only one thread(Main Thread) but still i m getting CME ..why?
is it because Iterator?
if i m replacing AL with COWAL than i don't get any Exception but i don't have the element "D" as well..why?
AL<String> l=new AL<>();
l.add("a");
l.add("b");
l.add("c");
Iterator<String> itr=l.iterator();
l.add("d");
while(itr.hasNext())
{
String s=itr.next();
Sop(s);
}
答案 0 :(得分:1)
Error is because line
l.add("d");
you are modifying list structure (Adding or removing Element) after Iterator has been created.
when you are calling
itr.next();
Internally it is checking any structure changes in list (Addition or removal in ArrayList) and it founds that there is one element added and hence size of array list has changed.. That's why you are getting that Exception.
If you will add that element before creation of Iterator or after using iterator you'll not get this error..
below is the code of next() in ArrayList Class;
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
......
return (E) elementData[lastRet = i];
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
答案 1 :(得分:1)
You are getting public function save(array $options = null, $sessionKey = null)
{
// ...
}
because ConcurrentModificationException
's iterator is fail-fast by design. Which means is that once the iterator is created, if the ArrayList
is modified(addition or removal of element), it will throw ArrayList
.
If you check the exception log statement, it is thrown at line ConcurrentModificationException
by String s=itr.next();
method because itr.next()
method of iterator checks for modification by calling next()
method of size of checkForComodification()
using ArrayList
variable which it copies while creating iterator from list.
Now lets talk about the modCount
where you are not getting this exception is because CopyOnWriteArrayList
is a thread-safe varient of CopyOnWriteArrayList
in which all mutative operations like add, remove, set are implemented by copying the internal array to new one and replace old array with newly created one.
So when you get iterator from list it holds a reference of array, and when you add an element to list, the list is having altogether new array. And iterator is still pointing the old array.
You might have noticed that the newly added element by statement ArrayList
is not printed on console. But if you print the whole list, it is there.
Here is your sample code with l.add("d");
:
CopyOnWriteArrayList
The output is produce is:
List<String> l = new CopyOnWriteArrayList<>();
l.add("a");
l.add("b");
l.add("c");
Iterator<String> itr = l.iterator();
l.add("d");
while (itr.hasNext()) {
String s = itr.next();
System.out.println(s);
}
System.out.println(l);
Hope this helps. Enjoy :)