Why does java concurrentmodificationexception affect arraylists and not standard arrays?

自古美人都是妖i 提交于 2019-12-11 06:46:59

问题


I saw a blog a while back that said if you're having trouble with concurrentmodificationexception, convert the arraylist to a regular array[] and you'll be fine. It didn't explain it though.

Why is this?


回答1:


The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException.

Notice that this exception does not indicate that the object has been concurrently modified by a different thread. The exception is thrown even one thread is violating an object’s contract.

In Java, a ConcurrentModificationException can occur when attempting to modify a Collections object (ex, java.util.List) outside of an Iterator. The documentation points to threads as a possible cause, but you can get this exception even doing single-threaded programming.

The following code throws a ConcurrentModificationException despite being executed in a single thread.

List<String> mylist = new ArrayList<String>();
mylist.add("one");
Iterator<String> iterator = mylist.iterator();
while( iterator.hasNext() ) {
  iterator.next();
  mylist.remove(0);  // throws the exception
}

The remove() call on the mylist interferes with the iterator processing. The correct way to remove an item while iterating is to use java.util.Iterator's remove() method (this is different than java.util.List.remove(int)).

If your maintaining an application and see this exception, chances are the bug is not as easy to detect as the preceding code block. Look for all remove() calls and make sure that they are all called outside of an iterator (as in a for loop with an index) or within an iterator (using iterator.remove()).

IllegalStateException

A related error is an IllegalStateException. This can occur if you don't advance the iterator after a remove().

iterator.next();
iterator.remove();
iterator.remove();  // will throw the error

Keep the iterator pointer current, operating one element at a time with next() or remove(); This is from Here.




回答2:


When you add or remove an element from an ArrayList, you are changing its structure. This would invalidate any iterator that was initialized before this change.

Arrays, on the other hand, have no real iterators. myArray[i] = myValue is just an assignment - it does nothing to the array's structure, and is atomic, like any other assignment.



来源:https://stackoverflow.com/questions/24219152/why-does-java-concurrentmodificationexception-affect-arraylists-and-not-standard

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!