并发修改异常源码分析_兰林汉的驴粉丝儿的博客-程序员秘密

技术标签: java  学习笔记  

//并发修改异常:运行以下下代码会抛出该异常--ConcurrentModificationException
  List<String> list = new ArrayList<String>();
        list.add("hello");
        list.add("world");
        list.add("java");

        Iterator<String> it = list.iterator();
        while(it.hasNext()){
    
            String s = it.next();
            if (s.equals("hello")){
    
                list.add("javaee");
            }
            System.out.println(s);
        }

/*运行结果:
    hello
    Exception in thread "main" java.util.ConcurrentModificationException
      	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:911)
      	at java.util.ArrayList$Itr.next(ArrayList.java:861)
      	at it.heima.date0803.Demo.main(Demo.java:95)
异常指向next方法,该方法是迭代器it调用,迭代器是接口,由List对象调用iterator方法返回,List的对象是ArrayList
向上转型,找到ArrayList, 查看重写的iterator方法,并且我们使用list对象调用add方法,一并找到ArayList中的add
方法,继续跟进iterator()中返回的Itr,发现他是内部类,无参构造权限修饰符为默认,Itr() {},属性分别为
0,-1,0,然后调用next方法,方法中先调用checkForComodification();这个方法中做判断
if(modCount != expectedModCount),就会抛出并发修改异常ConcurrentModificationException();
在list.add时候,ArrayList对象调用了add方法,首先走这个ensureCapacityInternal(size + 1),
这里面 modCount++;所以Itr判断时候modCount != expectedModCount,抛出异常*/

     public class ArrayList<E> extends AbstractList<E>implements List<E>{
    
         public Iterator<E> iterator() {
    
                 return new Itr();
             }
         public boolean add(E e) {
    
             ensureCapacityInternal(size + 1);  // Increments modCount!!
             elementData[size++] = e;
             return true;
         }
     }

    // Itr类:
      private class Itr implements Iterator<E> {
    
             int cursor;       // index of next element to return
             int lastRet = -1; // index of last element returned; -1 if no such
             int expectedModCount = modCount;
             Itr() {
    }
             public E next() {
    
                 checkForComodification();
                 int i = cursor;
                 if (i >= size)
                     throw new NoSuchElementException();
                 Object[] elementData = ArrayList.this.elementData;
                 if (i >= elementData.length)
                     throw new ConcurrentModificationException();
                 cursor = i + 1;
                 return (E) elementData[lastRet = i];
             }
             final void checkForComodification() {
    
                 if (modCount != expectedModCount)
                     throw new ConcurrentModificationException();
             }
         }

 
       private void ensureExplicitCapacity(int minCapacity) {
    
              modCount++;
      
              // overflow-conscious code
              if (minCapacity - elementData.length > 0)
                  grow(minCapacity);
          }
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_60283557/article/details/119358401

智能推荐

瓜子大数据架构首曝光:掩藏在“二手车”背后的技术思考_别盲目追风的博客-程序员秘密

提起 车好多集团,可能有些人会感到陌生,但提起瓜子二手车、毛豆新车,想必都十分熟悉,脍炙人口的广告语使得大家忽视了这家公司的技术能力。车好多集团旗下拥有瓜子二手车、毛豆新车、车速拍与瓜子养车四大品牌,协同为用户提供新车、二手车交易服务、汽车金融、售后保障、汽车维修保养等全产业链服务。对汽车而言,大部分用户目前的消费习惯倾向于线上看车、咨询、预约,线下进行交易,这对车好多集团的大数据架构搭建提出...

经典的数据湖“不可能三角”,如何有效解决?_数据库不可能三角_Lucifer三思而后行的博客-程序员秘密

提到数据湖就要先说一下数据仓库,数据仓库是集成多业务系统数据、面向主题的、专门用于数据查询分析的数据组织形式。当业务系统数据量不断增大、业务系统数量不断增多以后,数据仓库的出现就会成为必然。...

recycleview的动态添加与删除_搬砖小能手88的博客-程序员秘密

在学习完简单的recycleview后,我发现它还可以添加删除,特意在自己的工程中进行了实现首先,recycleview控件存在与v7包中,我们在写代码前要导入依赖包:compile 'com.android.support:appcompat-v7:25.0.0'compile 'com.android.support:recyclerview-v7:25.0.0'再看一下

图像的频域滤波增强_频域滤波增强的基本流程_御坂御坂Matlab工作室的博客-程序员秘密

文章目录1.低通滤波器图像的频域滤波增强是利用图像变换方法将原来图像空间中的图像以某种形式转换到其它空间中,然后利用该空间的特有性质再进行图像处理,最后转换回原来的图像空间中,从而得到处理后的图像。频域滤波增强的主要步骤如下:(1)选择变换方法,将输入图像变换到频域空间;(2)在频域空间中,根据目标设计一个转移函数并进行处理;(3)将所得的结果用反变换得到图像的增强。1.低通滤波器图像...

POJ - 3111 K Best (二分 + 01分数规划)_77458的博客-程序员秘密

K BestTime Limit: 8000MS Memory Limit: 65536KTotal Submissions: 8586 Accepted: 2203Case Time Limit: 2000MS Special JudgeDescriptionDemy has n jewels.

linux定时任务存放目录_linux定时任务文件路径_jacklin_001的博客-程序员秘密

寻找服务器上定时任务,主要是通过下方三个方法:1:crontab -e直接进入vi模式添加。此任务保存在、/var/spool/cron 里面对应的用户名文件2./etc/crontab 此计划任务所有人可用,但是 * * * * * 用户名 commend (多了个用户名添加)3.查看调度任务:crontab -l //列出当前的所有调度任务定时任务的几个示例及解释每天凌晨1点半备份数据库30 1 * * * /bin/bash /home/cnlot3/bin/backup_mys

随便推点

android重力感应模拟器sensorsimulator_hfwangjxin77的博客-程序员秘密

最近在研究android重力感应相关技术,郁闷的是在每次写完demo后,都必须放到真机上运行才能看到效果,于是就上网找了找,发现了一个android重力感应模拟器的插件。非常实用。不敢吃独食,特与广大鲲友分享之。 这个插件名字叫做sensorsimulator,是一个开源的项目,配备起来有点麻烦。1.首先将附件中的sensorsimulator-1.0.0-beta1.zip 解压缩,解压后我们会看到它的下面有几个文件夹,有个lib的文件夹,那个就是我们要的lib,在我们的项目下创建文件夹lib,然后通过e

基础_dongbeng4152的博客-程序员秘密

1.有变量name = "aleX leNb" 完成如下操作:# 1)移除 name 变量对应的值两边的空格,并输出处理结果name = "aleX leNb"print(name.strip())# 2)移除name变量左边的"al"并输出处理结果print(name.split("al"))print(name.lstrip("al"))print(n...

extjs6实现跨页勾选_extjs实现列表跨页全选_cxhao_123的博客-程序员秘密

最近公司的Extjs6项目遇到了一个分页勾选的bug,分享一下自己这两天的经验。话不多说,直接上代码:下面写得是一个window,/** * 人员选择公共组件,调用时配置以下参数,有什么参数组件就传值给什么组件 * memberNameCmp 名称显示框object * memberIdCmp id存储框object * memberGridCmp grid存储object

axi时序图_AXI4 & AXI4-stream 相关笔记_阳淼的博客-程序员秘密

2020.04.02更新:最近正好用到了这个,贴个能用的代码帮助大家理解吧。该代码已通过仿真测试,可以与Xilinx的AXI BRAM Controller一起使用。该模块的主要功能是利用AXI4协议对内存进行先写后读的反复操作。代码如下:`timescale 1ns / 1ps////////////////////////////////////////////////////////////...

vue js 获取不同时区的当前时间,在特定时区格式化时间戳_vue获取时区_郝艳峰Vip的博客-程序员秘密

前言在做跨境电商项目的时候,遇到一个设置广告营销的跨时区的时间不匹配导致广告不能同步的问题,所以就想着如何解决。相看到这个标题就会想到用时间戳解决这个问题,我一开始也是用的时间戳直接格式化的时间,(时间戳在全时间每个时区都是相同的),但是这样会有一个问题,就是你的服务器在北京,这样你的项目在美国中部标准时区(西六区)访问转时间戳出来的时间还是北京时间(东八区)出现这个问题的原因是我用得moment.js换的时间,所以导致代码在哪里就转的那个时间,后来就采用了指定时区的办法,就得已完美解决。解决

springmvc Validator @Valid注解后[email protected]导致请求404_li905663280的博客-程序员秘密

错误表象@Valid注解后404,无法访问如果控制台没有报错。可以在org.springframework.web.servlet.DispatcherServlet#doDispatch 进行断点,会进入catch异常语句,看异常详细信息。HV000030: No validator could be found for constraint ‘javax.validation.constraints.Pattern’ validating type ‘java.lang.Integer’. C

推荐文章

热门文章

相关标签