从ArrayList中删除元素时发生ConcurrentModificationException
当我运行下面的代码时,Java抛出ConcurrentModificationException。 Anyidea为什么?
Java is throwing ConcurrentModificationException when i am running following code. Anyidea why is that ?
ArrayList<String> list1 = new ArrayList<String>();
list1.add("Hello");
list1.add("World");
list1.add("Good Evening");
for (String s : list1){
list1.remove(2);
System.out.println(s);
}
ConcurrentModificationException 的文档,您会发现 p>
If you take a look at documentation of ConcurrentModificationException you will find that
当不允许修改对象时,检测到并发
修改的方法可能抛出此异常。
This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.
例如,通常不允许一个线程修改
a集合,而另一个线程正在迭代
...
请注意,这个异常并不总是表示一个对象有
被不同的线程同时修改。如果单个线程
发出一系列违反
对象的方法调用,那么该对象可能会抛出此异常。 例如,如果
线程在使用fail-fast迭代器迭代
集合时直接修改集合,则迭代器将抛出此
异常。
Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.
重要的是这个例外是我们不能保证它会一直被抛出,如文档
Important thing about this exception is that we can't guarantee it will always be thrown as stated in documentation
注意,fail-fast行为不能保证是正常的,一般是
,不可能在
存在时做任何硬的保证非同步并发修改。 快速操作在尽力而为的基础上抛出ConcurrentModificationException
。
也可从 ArrayList 文档
此类的
迭代器返回的迭代器
和listIterator
方法快速失败:如果列表在任何$ b $除了通过
迭代器自己的remove或add方法之外,迭代器创建之后的任何时候,迭代器都会抛出一个ConcurrentModificationException
。
The iterators returned by this class's
iterator
andlistIterator
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 aConcurrentModificationException
.
(强调我)
操纵Collection(在你的情况下List)的内容,而通过增强型for循环遍历它的内容,因为你不是通过迭代器for-each在内部使用。
So you can't manipulate content of Collection (in your case List) while iterating over it via enhanced for loop because you are not doing it via iterator for-each is using internally.
要解决它,只需要自己的迭代器
并在你的循环中使用它。要从集合中删除元素,请使用 remove
,如下例所示
To solve it just get your own Iterator
and use it in your loop. To remove elements from collection use remove
like in this example
Iterator<String> it = list1.iterator();
int i=0;
while(it.hasNext()){
String s = it.next();
i++;
if (i==2){
it.remove();
System.out.println("removed: "+ s);
}
}