In Java, how can this raise a ConcurrentModificationException in a single program with multiple threads?

I read this Freqqent Java concurrency question and was confused by the answer talking about java. util.ConcurrentModificationException .

My understanding of the answer is that this can happen in a single threaded program. How or what conditions cause the following code to throw an exception?

List<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c")); for (String string : list) { list.remove(string); } 
+6
java concurrency concurrentmodification
source share
3 answers

This snippet will always throw a ConcurrentModificationException .

The rule is this: you cannot change (add or remove elements from the list), iterate over it using Iterator (what happens when you use the for-each loop).

Please note, however, that you are allowed to modify the list through an iterator (because then it knows about the change and can take it into account) using Iterator.remove or ListIterator.add .

From the docs:

The iterators returned by this class iterator method and listIterator methods fail: if the list changes at any time after creating the iterator, in any way other than using its own methods to remove or add an iterator, the iterator will throw a ConcurrentModificationException.

The word "parallel" here means that you modify the list during a crawl.

+14
source share

You change the list as you scroll.

Here, ConcurrentModificationException has nothing to do with threads.

Attention! The following example is provided here to show how dangerous it can be to use a collection when changing it. This is not exactly what happened in the case of OP (loop through iterator and change)

I think it would be easier to imagine what is wrong with him if you use an old-fashioned loop with such a counter:

 List<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c")); for (int i = 0; i < list.size(); i++) { list.remove(i); //removes element at given index } 

Now the first time i is 0, and the 0th element has been deleted. The second time i is 1, so now the 1st element is removed. But, what is now 1st, it used to be 2nd, before the first removal. So, what used to be 1, and now 0, will never be deleted.

+2
source share

Because you remove from the list and iterate on it using an iterator at the same time.

See equivalent code using iterator.

 import java.lang.*; import java.util.*; class Test{ public static void main(String[] argv){ List<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c")); Iterator<String> itr=list.iterator(); while(itr.hasNext()){ String a=itr.next(); list.remove(a); } } } 

Right code

 import java.lang.*; import java.util.*; class Test{ public static void main(String[] argv){ List<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c")); Iterator<String> itr=list.iterator(); while(itr.hasNext()){ itr.remove(); } } } 
+2
source share

All Articles