我是靠谱客的博主 兴奋乌龟,最近开发中收集的这篇文章主要介绍fail-fast策略以及fail-safe是什么?,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

什么是fail-fast?
简单的来说就是优先考虑出现异常的场景,当异常产生时,直接抛出异常,程序终止。
在jcl中的fail-fast?
fail-fast只要是体现在当我们在遍历集合元素的时候,经常会使用迭代器,但在迭代器遍历元素的过程中,如果集合的结构被改变的话,就会抛出异常ConcurrentModificationException,防止继续遍历。这就是所谓的快速失败机制。
这里要注意的这里说的结构被改变,是例如插入和删除这种操作,只是改变集合里的值的话并不会抛出异常。

public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Java");
list.add("C++");
list.add("Python");
list.add("PHP");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String str = iterator.next();
if (str.equals("PHP")) {
list.remove(str);//因为移除了元素会抛异常
}
System.out.println(str);
}
}

这种机制最大的作用就在于多线程时保证多线程场景下不产生 “脏读”,一旦有线程在读取另一个线程想要更改就会直接抛出异常,可是直接抛出异常并不是我们想要的结果,应该采用线程安全的集合。
什么是fail-safe?
当我们对集合结构上做出改变的时候,fail-fast机制就会抛出异常。但是,对于采用fail-safe机制来说,就不会抛出异常。这是因为,==当集合的结构被改变的时候,fail-safe机制会在复制原集合的一份数据出来,然后在复制的那份数据遍历。==比如CopyOnWriteArrayList这个juc包下的线程安全集合类,就使用了fail-safe这个策略。

//CopyOnWriteArrayList 的 add方法
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}

以这个集合的add为例,为什么CopyOnWriteArrayList不会抛ConcurrentModificationException异常就在于copy原来的array,再在copy数组上进行add操作,这样做就完全不会影响CopyOnWriteArrayList中的array了。当然像其他的如remove、clear等方法也使用相同的策略。

fail-safe的缺点
从上面的两个核心操作可以看出,fail-safe有一定的缺陷
1.复制时需要额外的空间和时间上的开销。
2.由于都是复制原来的数组,多线程时可能就不能保证遍历的是最新内容。

最后

以上就是兴奋乌龟为你收集整理的fail-fast策略以及fail-safe是什么?的全部内容,希望文章能够帮你解决fail-fast策略以及fail-safe是什么?所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部