欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【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