概述
首先要弄明白同步修改的概念,指的是一个或者多个线程正在遍历一个集合,此时另一个线程修改了Collection的数据结构(添加,删除或者修改);
1.fail-fast机制
fail-fast机制在集合被遍历时,如果集合元素被修改,直接抛出Concurrent Modification Exception,有两种情况;
1>单线程环境下
集合被创建后,在遍历它的过程中修改了结构。注意 remove()方法会让expectModcount和modcount 相等,所以是不会抛出这个异常。
2>多线程环境下
一个线程在遍历元素时,另一个线程对元素进行了修改
fail-fast机制校验的原理是内部维护了一个标识“mode”,当集合数据结构被修改时,修改mode;在每次遍历的next和hasNext方法会去检验“mode”是否被修改,若修改则抛出Concurrent Modification Exception
例如ArrayList迭代部分的源码
private class Itr implements Iterator {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
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 void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
2.fail-safe机制
fail-safe机制在每次对集合进行修改时会复制一个新的对象,因此不会抛出ConcurrentModificationException,
fail-safe机制有两个问题
(1)需要复制集合,产生大量的无效对象,开销大
(2)无法保证读取的数据是目前原始数据结构中的数据。
3.fail-fast和fail-safe机制例子
package com.example.springbootDemo.service;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class FailFastExample {
public static void main(String[] args) {
Map premiumPhone = new HashMap();
premiumPhone.put("Apple", "iPhone");
premiumPhone.put("HTC", "HTC one");
premiumPhone.put("Samsung","S5");
Iterator iterator = premiumPhone.keySet().iterator();
while (iterator.hasNext())
{
System.out.println(premiumPhone.get(iterator.next()));
premiumPhone.put("Sony", "Xperia Z");
}
}
}
package com.example.springbootDemo.service;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
public class FailSafeExample {
public static void main(String[] args) {
ConcurrentHashMap premiumPhone =
new ConcurrentHashMap();
premiumPhone.put("Apple", "iPhone");
premiumPhone.put("HTC", "HTC one");
premiumPhone.put("Samsung","S5");
Iterator iterator = premiumPhone.keySet().iterator();
while (iterator.hasNext())
{
System.out.println(premiumPhone.get(iterator.next()));
premiumPhone.put("Sony", "Xperia Z");
}
System.out.printf("premiumPhone:"+premiumPhone.toString());
}
}
最后
以上就是老实音响为你收集整理的fail safe java_java中fail-fast 和 fail-safe的区别的全部内容,希望文章能够帮你解决fail safe java_java中fail-fast 和 fail-safe的区别所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复