Fail-Fast
程序员文章站
2022-05-23 13:03:43
...
本文大部分内容来源于网络,如有侵权,请站内联系。
什么是 fail-fast ?
一个 fail-fast 的系统是指当发现任何可能导致过程失败的情况时,立刻抛出错误。一个 fail-fast 的迭代器是指当迭代的集合正在迭代时检测到集合发生了修改,就立刻抛出一个异常。
ArrayList 的 fail-fast 的实现
public class ArrayList {
// 用来记录修改次数(继承自 AbstractList)
protected transient int modCount = 0;
add() / remove() / trimToSize() / ensureCapacity() ... {
// 每次修改, modCount 均自增
modCount++;
}
class Iter implements Iterator<E> {
// 记录 modCount 当前值(一次快照)
int expectedModCount = modCount;
public E next() {
// next() 操作之前, check 一次
checkForComodification();
...
}
public void remove() {
// remove() 操作之前, check 一次
checkForComodification();
...
ArrayList.this.remove(lastRet);
...
// 更新 expectedModCount 。这说明通过 iter 的 remove() 来删除元素不会抛出 ConcurrentModificationException
expectedModCount = modCount;
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
}
如何一边遍历一边修改?
1. 使用迭代器;
Iterator<Integer> iter = list.iterator();
while (iter.hasNext()) {
int item = iter.next();
if (item % 2 == 0) {
iter.remove();
}
}
2. 使用 CopyOnWriteArrayList ;
3. 不要边遍历边修改,使用 temp 。
ConcurrentModificationException 这个异常看起来像是“多线程并发修改异常”,其实单线程下的迭代时修改也可能会出现这个异常。单线程下,迭代时通过集合自身的操作修改集合,会引发异常;通过迭代器修改(即 iter.remove() )不会引发。多线程下,迭代时通过迭代器修改可能会引发 ConcurrentModificationException ,此时应该使用线程安全的集合。
什么是 fail-fast ?
一个 fail-fast 的系统是指当发现任何可能导致过程失败的情况时,立刻抛出错误。一个 fail-fast 的迭代器是指当迭代的集合正在迭代时检测到集合发生了修改,就立刻抛出一个异常。
ArrayList 的 fail-fast 的实现
public class ArrayList {
// 用来记录修改次数(继承自 AbstractList)
protected transient int modCount = 0;
add() / remove() / trimToSize() / ensureCapacity() ... {
// 每次修改, modCount 均自增
modCount++;
}
class Iter implements Iterator<E> {
// 记录 modCount 当前值(一次快照)
int expectedModCount = modCount;
public E next() {
// next() 操作之前, check 一次
checkForComodification();
...
}
public void remove() {
// remove() 操作之前, check 一次
checkForComodification();
...
ArrayList.this.remove(lastRet);
...
// 更新 expectedModCount 。这说明通过 iter 的 remove() 来删除元素不会抛出 ConcurrentModificationException
expectedModCount = modCount;
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
}
如何一边遍历一边修改?
1. 使用迭代器;
Iterator<Integer> iter = list.iterator();
while (iter.hasNext()) {
int item = iter.next();
if (item % 2 == 0) {
iter.remove();
}
}
2. 使用 CopyOnWriteArrayList ;
3. 不要边遍历边修改,使用 temp 。
ConcurrentModificationException 这个异常看起来像是“多线程并发修改异常”,其实单线程下的迭代时修改也可能会出现这个异常。单线程下,迭代时通过集合自身的操作修改集合,会引发异常;通过迭代器修改(即 iter.remove() )不会引发。多线程下,迭代时通过迭代器修改可能会引发 ConcurrentModificationException ,此时应该使用线程安全的集合。