• fail-fast以及Iterator对象


    Iterator对象在foreach循环的时候只能使用自己的remove/add方法,如果使用了集合的remove/add方法或者其他线程并发时修改了集合的内容,就属于fail-fast机制,即是一个错误,但是该错误会尽最大可能地抛出ConcurrentModificationException异常,该异常应尽量作为一个bug的检测。

    public class Test1 {
    public static void main(String[] args) {
    List<String> ls=new ArrayList<String>();
    ls.add("Bob");
    ls.add("Jia");
    for(Iterator it=ls.iterator();it.hasNext();) {//这里的Iterator对象是一个List对象的另一种形式,头指针不包含元素,只包含头指针。每次的next方法都会输出下一个元素。
    if ("Bob".equals(it.next())) {//这里会得到"Bob"。
    ls.remove(0);//这里使用ls来移除或添加,那么操作过后总长度是变了的,会和Iterator对象长度不符,因此调用Iterator对象的next等方法会抛出Concurrent...异常。
    System.out.println(it.next());//所以这里会抛出异常,不管是ls移除任意位置索引。除非Iterator调用自身方法移除队头元素即用it来移除就是remove()方法无参数,表示移除。

    //但是如果把上述调用it.next()给注释掉,就不会抛出异常。当没有用hasNext来检验时,调用next()方法可能该元素不存在,会抛出NoSuchElementException异常。

    //如果是并发操作,记得给Iterator对象上锁哦。

    //通俗一点理解就是iterator方法就是说我要遍历ls的那几个元素我都做上记号,如果ls把他们删除或添加了,我这个Iterator遍历的范围同样随之改变(就是说我的next方法会动态改变),但是增加元素我这里是没有记号的,删除元素我这里有记号但是你没有元素也对不上,记号就对不上了自然会抛出异常。而Iterator对象本身的移除方法则是说我不遍历你了,就没有记号对不上一说。

    }
    }
    }

    总结。

    准确的说,在调用迭代器的时候,会有两个属性modCount和expectedModCound他们的值相等,当使用迭代器的remove方法移除集合元素时,不仅修改modCount的值,还会修改到expectedModCount的值使他们同步变化,而调用集合的移除或添加方法则只会修改mc的值,不会修改emc的值。这两个值不相等时就会抛出ConcurrentModificationException异常。

    再总结。

    iterator和集合假设为list的remove()方法都会删除掉集合里的对象,list有属性modCount,在利用iterator()方法的时候会创建一个单链索引表指向集合对象,但是list删除对象不会同步该单链索引表,因为该表是iterator里面的东西,可以把单链索引表看作expectedModCount,由此他们不匹配,会抛出异常。而如果利用iterator删除对象,不仅会删除集合里的元素修改modCount的值,还会同步索引表,也就是同步expectedModCount的值。上述的索引表相当于是一个引用,指向集合对象。该引用保存在Iterator对象里。我调用iterator的remove()方法实际上就是利用该引用来删除集合元素,又利用该引用得到删除元素后的集合的modCount值,将其赋给expectedModCount,由此实现匹配。而利用list的remove方法我这个iterator是感知不到的,而next方法和hasNext方法只会判断expectedModCount和modCound是否相等,相等则执行,否则抛出ConcurentModificationException异常。

    抛出ConcurrentModificationException异常的原因

  • 相关阅读:
    EF ObjectQuery查询及方法
    Entity Framework --Entity SQL注意事项
    EF中Entity SQL用法
    Navicat for Oracle设置唯一性和递增序列
    Oracle添加自增长字段方法步骤
    MVC5项目中添加Wep API
    C#版 Winform界面 Socket编程 Client客户端
    C#版 Winform界面 Socket编程 Server服务器端
    给缺少Python项目实战经验的人
    python模块之collections
  • 原文地址:https://www.cnblogs.com/riverer/p/qqq321.html
Copyright © 2020-2023  润新知