java中fail-fast和fail
转自:
http://www.java265.com/JavaJingYan/202206/16540696313601.html
下文笔者讲述fail-fast和fail-safe的区别说明,如下所示
同步修改简介说明
同步修改(并发修改)指: 当一个或多个线程正在遍历一个集合Collection 此时另一个线程修改了这个集合的内容(添加,删除或修改)
fail-fast机制
fail-fast机制:
在遍历一个集合时,当集合结构被修改,会抛出Concurrent Modification Exception
fail-fast:
会在以下两种情况下抛出ConcurrentModificationException
1.单线程环境
集合被创建后,在遍历它的过程中修改了结构。
注意:
remove()方法会让expectModcount和modcount相等,所以是不会抛出这个异常
2.多线程环境
当一个线程在遍历这个集合,而另一个线程对这个集合的结构进行了修改
注意事项:
迭代器的快速失败行为无法得到保证,
因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证
快速失败迭代器会尽最大努力抛出 ConcurrentModificationException
因此,为提高这类迭代器的正确性而编写一个依赖于此异常的程序是错误的做法:迭代器的快速失败行为应该仅用于检测bug
fail-fast机制检测方法分享
迭代器在遍历过程中是直接访问内部数据的 因此内部的数据在遍历的过程中无法被修改 为了保证不被修改,迭代器内部维护了一个标记"mode", 当集合结构改变(添加删除或者修改) 标记"mode"会被修改,而迭代器每次的hasNext()和next()方法都会检查该"mode"是否被改变 当检测到被修改时,抛出Concurrent Modification Exception 下面看看ArrayList迭代器部分的源码
private class Itr implements Iterator<E> {
int cursor;
int lastRet = -1;
int expectedModCount = ArrayList.this.modCount;
public boolean hasNext() {
return (this.cursor != ArrayList.this.size);
}
public E next() {
checkForComodification();
/** 省略此处代码 */
}
public void remove() {
if (this.lastRet < 0)
throw new IllegalStateException();
checkForComodification();
/** 省略此处代码 */
}
final void checkForComodification() {
if (ArrayList.this.modCount == this.expectedModCount)
return;
throw new ConcurrentModificationException();
}
}


