首页 > 其他分享 >迭代器遍历对象 快速失败和安全失败

迭代器遍历对象 快速失败和安全失败

时间:2022-09-26 00:55:34浏览次数:46  
标签:遍历 迭代 modCount 修改 失败 集合

一、快速失败(fail—fast)

在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加、删除、修改),则会抛出 Concurrent Modification Exception。

原理:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化,就会改变 modCount 的值。每当迭代器使用 hashNext()/next() 遍历下一个元素之前,都会检测 modCount 变量是否为 expectedmodCount 值,是的话就返回遍历;否则抛出异常,终止遍历。

注意:这里异常的抛出条件是检测到 modCount != expectedmodCount 这个条件。如果集合发生变化时修改 modCount 值刚好又设置为了 expectedmodCount 值,则异常不会抛出。因此,不能依赖于这个异常是否抛出而进行并发操作的编程,这个异常只建议用于检测并发修改的 bug。

场景:java.util 包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改)。

 

二、安全失败(fail—safe)

采用安全失败机制的集合容器,在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历。

原理:由于迭代时是对原集合的拷贝进行遍历,所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,所以不会触发 Concurrent Modification Exception。

缺点:基于拷贝内容的优点是避免了 Concurrent Modification Exception,但同样地,迭代器并不能访问到修改后的内容,即:迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间原集合发生的修改迭代器是不知道的。

标签:遍历,迭代,modCount,修改,失败,集合
From: https://www.cnblogs.com/cxygg/p/16729532.html

相关文章

  • 数组遍历的方法
    数组遍历的方法forEach类似与for循环不会改变原数组将数组中的2全部加1constarr=[1,2,3,2]varnewArr=[]arr.forEach(v=>{if(v===2){v=v+1}......
  • 二叉树遍历
    应用实例代码实现publicclassBinaryTreeDemo{ publicstaticvoidmain(String[]args){ //先需要创建一颗二叉树 BinaryTreebinaryTree=newBinary......
  • 树的遍历
    二叉树的遍历应用实例前序遍历,中序遍历,后序遍历步骤前序遍历1.先输出当前节点2.如果当前节点的左子节点不为空,则递归前序遍历3.如果当前节点的右子节点不为空,则递归......
  • mozjpeg进行压缩时失败
    参考链接:npm安装包时报错[email protected]半亩方塘(bluepost.cn)(1条消息)mozjpeg安装失败/Failedatthemozjpeg_imH......
  • Python 异步迭代器
    1、参考来源https://docs.python.org/zh-cn/3.9/reference/datamodel.html?highlight=aiter#asynchronous-iterators2、代码示例:1#-*-coding:utf-8-*-2"""......
  • unity hub 个人版许可证获取失败
    个人版许可证获取失败,项目都没法打开。可以退出再次登录,或重启电脑,操蛋事,找了半天证书,博文说删c盘文件,找都找不到https://developer.unity.cn/ask/question/62297ed9ed......
  • 算法竞赛进阶指南 0x24 迭代加深
    对于深度优先,如果答案在很浅的部位,但是整个搜索树过于深,那么就会寄掉。但是对于广度优先,本来挺好,但是在队列里面存储太多的元素,到时爆。同时,广度优先也不容易存储数据。......
  • linux 启动mysql失败 InnoDB: Table flags are 0 in the data dictionary but the fla
    linux启动mysql失败,报错日志文件里的报错信息InnoDB:Tableflagsare0inthedatadictionarybuttheflagsinfile./ibdata1are0x4800!执行 sudosystemctl......
  • 使用传统的方式,遍历集合,对集合中的数据进行过滤和使用Stream流的方式,遍历集合,对集合中
    使用传统的方式,遍历集合,对集合中的数据进行过滤使用Stream流的方式,遍历集合,对集合中的数据进行过滤使用Stream流的方式,遍历集合,对集合中的数据进行过滤Stream流是JDK1.8......
  • 实例85 牛顿迭代法求解方程
    #include<stdio.h>#include<math.h>#include<stdlib.h>intFunction(double,double*,double*);intNewton(double*,double,int);intFunction(x,f,dy)dou......