【java基础】快速失败和安全失败
程序员文章站
2022-07-14 11:24:06
...
概念
快速失败(fail-fast):对于不安全的集合类在遍历过程中,对其进行增删改的时候,就会抛出ConcurrentModificationException,比如HashMap,ArrayList等。
安全失败(fail-safe):对于安全的集合类在遍历之前,安全集合类会在遍历之前会将原有集合拷贝一份副本,在副本集合中进行遍历,从而在对其原始类进行增删改的时候,并不会被迭代器检测到,固不会抛出ConcurrentModificationException异常,但对其原始集合类的修改也不会表现在副本集合上。
快速失败
直接看代码以及运行结果
public static void main(String[] args) {
final HashMap hashMap = new HashMap();
hashMap.put("a", 1);
hashMap.put("b", 2);
hashMap.put("c", 3);
Thread thread = new Thread() {
@Override
public void run() {
hashMap.put("d", 4);
}
};
Set set = hashMap.entrySet();
final Iterator iterator = set.iterator();
thread.start();
Thread thread1 = new Thread() {
@Override
public void run() {
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
};
thread1.start();
}
运行结果如下:
Exception in thread "Thread-1" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1445)
at java.util.HashMap$EntryIterator.next(HashMap.java:1479)
at java.util.HashMap$EntryIterator.next(HashMap.java:1477)
安全失败
测试代码
public static void main(String[] args) {
final ConcurrentHashMap hashMap = new ConcurrentHashMap();
hashMap.put("a", 1);
hashMap.put("b", 2);
hashMap.put("c", 3);
Thread thread = new Thread() {
@Override
public void run() {
hashMap.put("d", 4);
}
};
Set set = hashMap.entrySet();
final Iterator iterator = set.iterator();
thread.start();
Thread thread1 = new Thread() {
@Override
public void run() {
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
};
thread1.start();
}
测试结果:
a=1
b=2
c=3
d=4
总结
从快速失败和安全失败测试代码可以看出,快速失败中的集合HashMap,如果在遍历过程中,有其他线程添加其对应的值,会抛出ConcurrentModificationException异常,而安全失败中的集合ConcurrentHashMap在遍历过程中,其他线程添加其值,并不会抛出ConcurrentModificationException异常,而且会继续将拷贝出来的副本集合数据遍历结束。
上一篇: 活性失败、快速失败、安全失败
下一篇: Java 异常 throw和throws