简体   繁体   中英

Is throwing ConcurrentModificationException system dependent

I am working on a piece of code with Iterator and getting a ConcurrentModificationException at the line a when I run the program from my IDE on windows--

  LinkedList ll =new LinkedList();
  . . .
  . . . 
  Iterator iter = ll.iterator();
  int i=0;
   while (iter.hasNext()) {
       // GrammarSection agrammarSection = (GrammarSection) iter.next();  //a
       String s1 = (String) iter.next();
        ll.remove(i);
        i++;
   }

This is expected because Im modifying the list while I'm iterating so the fail-fast iterator throws a Concurrentmodification exception. However, when I run this code in unix with apache server, the next method of the iterator does-not throw any exception. So, does the concurrentmodification exception depend on OS level ?

No, it shouldn't. It should crash anyway.

I suppose it could be different on a different JVM, but according to the official spec , iterators on linked list should be fail-fast.

OS has nothing to do with it.

I found out what the issue might be. When your list has 2 elements, the hasNext() returns false and it works without an exception. If the list has 3 or more elements it throws an exception everywhere. So make sure your list has the right number of elements.

As for the OS dependence - java code is not OS dependent

Anyway - use iter.remove() - it will remove the element from the underlying list without causing the exception.

The problem with your approach is that you are modifying the underlying list without the iterator knowing anything of that modification. So you have to carry it out via the iterator.

Use iter.remove() ; not ll.remove(i)

If you use the iterator remove function, you will not get a concurrentmodificationexception.

However, to answer your question; the CME should not depend on OS level. There must be some other issue with your code as to why it is not throwing CME in unix.

BTW, the spec has the following comments

"Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs."

So, does the concurrentmodification exception depend on OS level ?

It does have some JMV-dependence, but not in the code you showed.

// LinkedLists have a member variable called modCount
// which is an integer which holds the count of modifications
// made on the list with methods like list.add() list.remove() etc.
LinkedList ll =new LinkedList();
. . .
. . . 
// When the iterator is created here, it copies the current modCount
// of the LinkedList into a member of its own called expectedModCount
Iterator iter = ll.iterator();
int i= 0;
while (iter.hasNext()) {
    // iter.next() calls a method called checkForComodification
    // which throws a ConcurrentModificationException if the
    // current modCount of the original LinkedList is different
    // from the expectedModCount on this iterator
    String s1 = (String) iter.next();
    ll.remove(i);
    i++;
}

When the list is accessed and iterated in different threads without proper synchronization, the modification made to LinkedList.modCount (when LinkedList.add , LinkedList.remove etc are called) might not be visible to the thread doing the iteration. So ConcurrentModificationException s are not guaranteed to be thrown, in general. But in the single-threaded code you showed, there should be no visibility problems and the exception should always be thrown if ll.remove() is ever called successfully after ll.iterator() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM