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

java fail-fast机制

程序员文章站 2022-04-07 18:24:43
概述fail-fast 机制是java集合(Collection)中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。例如:当某一个线程A通过iterator去遍历某集合的过程中,若该集合的内容被其他线程所改变了;那么线程A访问集合时,就会抛出ConcurrentModificationException异常,产生fail-fast事件。该机制设计的初衷在遍历集合元素的过程中,是不希望集合被修改的;不然会产生许多问题,比如:arraylist在遍历的过程中,...

概述

fail-fast 机制是java集合(Collection)中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。例如:当某一个线程A通过iterator去遍历某集合的过程中,若该集合的内容被其他线程所改变了;那么线程A访问集合时,就会抛出ConcurrentModificationException异常,产生fail-fast事件。

该机制设计的初衷

在遍历集合元素的过程中,是不希望集合被修改的;不然会产生许多问题,比如:
arraylist在遍历的过程中,元素被删除。此时后面的元素会进行移位,来填补空出来的位置;元素移位不是原子操作,相反元素较多的情况下,这个过程消耗的时间不短;元素位置调整的过程中,又进行遍历,肯定会产生不少问题,比如漏掉对元素的访问。
为此只要检测到集合被修改过,就应该快速的失败,并抛出异常。

该机制的实现

每个集合类都有一个成员变量,private transient int modCount = 0;
从字面意思代表集合被修改的次数,实际上就是代表数据的版本。每进行一次修改集合的操作(比如,list中的add,remove;map中的put等),modCount的值加一。
以Arraylist的代码为例:

    public boolean add(E e) {
        modCount++;
        add(e, elementData, size);
        return true;
    }

当遍历集合的时候,会用expectedModCount来保存modCount,然后每次访问元素的时候,都会判断两者是否相等,来检查集合是否被修改过。下面是ArrayList创建的迭代器。

    public Iterator<E> iterator() {
        return new Itr();
    }
    // Itr是内部类,可以访问到ArrayList的成员变量
    // 代码有删除
    private class Itr implements Iterator<E> {
        // modCount是ArrayList的成员变量,创建Itr会存储当前modCount
        // 后续遍历元素时,通过对比两者来判断集合是否修改过
        int expectedModCount = modCount;
        @SuppressWarnings("unchecked")
        public E next() {
            // 判断集合是否修改过
            checkForComodification();
            int i = cursor;
            Object[] elementData = ArrayList.this.elementData;
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }
        // iterator自己修改集合不会产生问题,因为调用者清楚自己在干啥
        // 删除元素的同时修改modCount,这样同时创建出来的两个迭代器,
        // 一个修改后,另外一个能够感知到
        public void remove() {
            ArrayList.this.remove(lastRet);
            cursor = lastRet;
            lastRet = -1;
            expectedModCount = modCount;
        }
        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

本文地址:https://blog.csdn.net/shuxiaohua/article/details/110234740

相关标签: java