概述
在Collection集合中,有线程安全和线程不安全这2大类的版本。对于线程不安全的类,并发情况下可能会出现fail-fast情况;而线程安全的类,可能出现fail-safe的情况。
fail-fast快速失败
当遍历一个集合对象时,如果集合对象的结构被修改了,就会抛出ConcurrentModificationExcetion异常。
以ArrayList的源码为例,讲解一下fail-fast的机制
1、modCount
protected transient int modCount = 0;
modCount:代表修改的次数,add、remove操作都会使得modCount自增。
2、array的Iterator中有expectedModCount
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
//A、期望的改变值
int expectedModCount = modCount;
Itr() {}
public boolean hasNext() {
return cursor != size;
}
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
}
public E next() {
// B、校验modCount和expectedModCount区别
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
fail-safe 安全失败
Fail-Safe 迭代的出现,是为了解决fail-fast抛出异常处理不方便的情况。fail-safe是针对线程安全的集合类;在java.util.concurrent 包中集合的迭代器,如 ConcurrentHashMap, CopyOnWriteArrayList等默认为都是Fail-Safe。
缺点是:
- iterator不能保证返回集合更新后的数据,因为其工作在集合克隆上,而非集合本身。
- 创建集合拷贝需要相应的开销,包括时间和内存。
最后
以上就是优秀大地为你收集整理的java基础:知道fail-fast,你知道fail-safe吗?的全部内容,希望文章能够帮你解决java基础:知道fail-fast,你知道fail-safe吗?所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复