St.*_*rio 3 java iterator arraylist
我试着通过编写以下代码来重现ConcurrentModificationException:
List<String> last = new ArrayList<>();
last.add("a");
last.add("b");
for(String i : last){
System.out.println(i);
last.remove(i);
}
System.out.println(last);
Run Code Online (Sandbox Code Playgroud)
既然,提到的文件ArrayList
请注意,迭代器的故障快速行为无法得到保证,因为一般来说,在存在不同步的并发修改时,不可能做出任何硬性保证.
我预计在单线程程序中,这种检测是直截了当的.但程序打印出来了
a
[b]
Run Code Online (Sandbox Code Playgroud)
代替.为什么?
您的代码等同于以下内容:
List<String> last = new ArrayList<>();
last.add("a");
last.add("b");
for(Iterator<String> i = last.iterator(); i.hasNext(); ) {
String value = i.next();
System.out.println(value);
last.remove(value);
}
System.out.println(last);
Run Code Online (Sandbox Code Playgroud)
for循环的流程是:
System.out.println(value); // prints "a"
last.remove(value); // removes "a" from the list
i.hasNext() // exits the loop, since i.hasNext() is false
System.out.println(last); // prints "[b]" - the updated list
Run Code Online (Sandbox Code Playgroud)
这就是为什么你得到你的输出而不是ConcurrentModificationException.ConcurrentModificationException如果你要在列表中添加另一个值(例如last.add("c")),你会得到的,因为i.hasNext()在第一次迭代之后它将是真的并且i.next()将抛出异常.
如文档中所述:
此类的 iterator 和 listIterator 方法返回的迭代器是快速失败的:如果在创建迭代器后的任何时间对列表进行结构修改,除了通过迭代器自己的 remove 或 add 方法外,迭代器将抛出 ConcurrentModificationException
因为您正在使用新语法for(String i : last)遍历列表,所以会为您创建一个迭代器,并且您无法在循环时修改该列表。
此异常与多线程无关。同样只使用一个线程,您可以抛出该异常。
内部有一个变量modCount,每次修改列表结构都会增加该变量。首次创建迭代器时,它会将 的值保存modCount在变量中expectedModCount。每个后续修改检查该值expectedModCount是否等于modCount。如果不是,ConcurrentModificationException则抛出一个。
我以添加remove的代码为例。同样的add,addAll和所有其他的方法是修改列表。
public E remove(int index) {
rangeCheck(index);
// Check if a modification should thrown a ConcurrentModificationException
checkForComodification();
E result = parent.remove(parentOffset + index);
this.modCount = parent.modCount;
this.size--;
return result;
}
final void checkForComodification() {
if (expectedModCount != ArrayList.this.modCount)
throw new ConcurrentModificationException();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1735 次 |
| 最近记录: |