-1

I have the following code which throws ConcurrentModificationException because I am using two different iterators on the same list and one of them is modifying the list. So, the second iterator throws the exception when reading the list because some other iterator has modified the list.

    List<Integer> list = new ArrayList<>();

    populate(list);//A method that adds integers to list

    ListIterator<Integer> iterator1 = list.listIterator();
    ListIterator<Integer> iterator2 = list.listIterator();

    while (iterator1.hasNext()) {
        if(iterator1.next() < 5)
            iterator1.remove();
    }

    while (iterator2.hasNext()){
        if(iterator2.next() < 5) {
         //Call handler   
        }
    }

My question is how does iterator2 know internally that the list has has been modified by some other iterator if it has not reached an element which is yet removed by iterator1? How does it figure out that some other iterator has mutated the list? One way could be keep track of size but that can't be the reason since some other iterator can just replace any element.

qrius
  • 621
  • 2
  • 9
  • 22
  • Why do you care? You created the iterator before you modified the list. There is likely a "dirty" flag but, again, why would you want to code like this to work? – stdunbar May 09 '17 at 02:50
  • 1
    I don't want a code like this to work. But I do care as to know how this scenario detected. – qrius May 09 '17 at 02:52
  • Use the Source it is freely available! –  May 09 '17 at 02:57
  • Didn't know would get penalties for such question! Will keep that in mind. – qrius May 09 '17 at 03:01

1 Answers1

5

A good way to answer questions like this is to look at the source code, for example the source code for ArrayList. Search for ConcurrentModificationException.

You should be able to tell that things work rather like this:

  • Collection objects have a modification count, which starts at zero and increases whenever an add or remove or similar operation occurs.
  • When an iterator object is created, we store the current modification count of the collection inside the iterator.
  • Every time the iterator is used, it checks the collection's mod count against the mod count the iterator got when it was created. If those values differ, the exception is thrown.

In your case, remove operations performed by iterator1 on the list change the structural operation count (modCount) of the list. When iterator2 is asked to remove, it sees its expectedModCount, which it received initially as 0, differing from the current mod count of the list.

It should be noted that it.remove is a special case. When an iterator does a remove itself, its expectedModCount adjusts accordingly, to keep in sync with the underlying list.

Ray Toal
  • 86,166
  • 18
  • 182
  • 232
  • Got the approach. Thanks! – qrius May 09 '17 at 03:00
  • You're welcome. The source code is pretty useful here and the names of variables and the comments are kind of cool. BTW I added a little more to the answer---someone (rightly) downvoted, I think, because I left out a technicality about an iterator doing a remove operation itself. It doesn't change the basic idea, but it is good to be complete here. – Ray Toal May 09 '17 at 03:06