java fail-fast机制
程序员文章站
2022-09-29 22:51:46
概述fail-fast 机制是java集合(Collection)中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。例如:当某一个线程A通过iterator去遍历某集合的过程中,若该集合的内容被其他线程所改变了;那么线程A访问集合时,就会抛出ConcurrentModificationException异常,产生fail-fast事件。该机制设计的初衷在遍历集合元素的过程中,是不希望集合被修改的;不然会产生许多问题,比如:arraylist在遍历的过程中,...
概述
fail-fast 机制是java集合(Collection)中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。例如:当某一个线程A通过iterator去遍历某集合的过程中,若该集合的内容被其他线程所改变了;那么线程A访问集合时,就会抛出ConcurrentModificationException异常,产生fail-fast事件。
该机制设计的初衷
在遍历集合元素的过程中,是不希望集合被修改的;不然会产生许多问题,比如:
arraylist在遍历的过程中,元素被删除。此时后面的元素会进行移位,来填补空出来的位置;元素移位不是原子操作,相反元素较多的情况下,这个过程消耗的时间不短;元素位置调整的过程中,又进行遍历,肯定会产生不少问题,比如漏掉对元素的访问。
为此只要检测到集合被修改过,就应该快速的失败,并抛出异常。
该机制的实现
每个集合类都有一个成员变量,private transient int modCount = 0;
从字面意思代表集合被修改的次数,实际上就是代表数据的版本。每进行一次修改集合的操作(比如,list中的add,remove;map中的put等),modCount的值加一。
以Arraylist的代码为例:
public boolean add(E e) {
modCount++;
add(e, elementData, size);
return true;
}
当遍历集合的时候,会用expectedModCount来保存modCount,然后每次访问元素的时候,都会判断两者是否相等,来检查集合是否被修改过。下面是ArrayList创建的迭代器。
public Iterator<E> iterator() {
return new Itr();
}
// Itr是内部类,可以访问到ArrayList的成员变量
// 代码有删除
private class Itr implements Iterator<E> {
// modCount是ArrayList的成员变量,创建Itr会存储当前modCount
// 后续遍历元素时,通过对比两者来判断集合是否修改过
int expectedModCount = modCount;
@SuppressWarnings("unchecked")
public E next() {
// 判断集合是否修改过
checkForComodification();
int i = cursor;
Object[] elementData = ArrayList.this.elementData;
cursor = i + 1;
return (E) elementData[lastRet = i];
}
// iterator自己修改集合不会产生问题,因为调用者清楚自己在干啥
// 删除元素的同时修改modCount,这样同时创建出来的两个迭代器,
// 一个修改后,另外一个能够感知到
public void remove() {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
本文地址:https://blog.csdn.net/shuxiaohua/article/details/110234740
下一篇: 一位老程序员的10条忠告