快速失败 fail-fast
在使用迭代器对于集合对象遍历,如果对集合进行了修改(添加、删除、修改),都会导致抛出ConcurrentModificationException异常。
java.util包下的集合都是快速失败。
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
list.add(4);
}
执行后效果如下:
在生成iterator是,会将ArrayList的modCount赋值给expectedModCount。 当iterator在执行next()、remove()方法是,会判断expectedModCount与modCount是否相等。若不相等,则抛出ConcurrentModificationException异常。
public E next() {
checkForComodification();
...
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
...
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
当ArrayList在进行新增、删除、修改操作时,会改变modCount的值。再使用iterator遍历的时候,就会抛出异常。
安全失败 fail-safe
遍历时不在原集合上遍历,而是先复制原集合内容,在拷贝的集合上进行遍历。
java.util.concurrent包下的集合都是安全失败的。
List list = new CopyOnWriteArrayList();
list.add(1);
list.add(2);
list.add(3);
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
list.add(4);
}
执行结果如下,遍历时。并不知道改变后的list。