当前位置: 首页> 财经> 创投人物 > 注册商标费用多少钱_查法人信息的系统_优化师_搜狗优化排名

注册商标费用多少钱_查法人信息的系统_优化师_搜狗优化排名

时间:2025/8/6 16:13:05来源:https://blog.csdn.net/2301_77599076/article/details/143469949 浏览次数:0次
注册商标费用多少钱_查法人信息的系统_优化师_搜狗优化排名

文章目录

  • 一、问题描述
  • 二、问题分析
  • 三、问题解决
  • 四、总结

  本篇是对于集合类源码浅析のArrayList中第五部分并发修改异常原因分析的扩展补充。


一、问题描述

  我们首先看一段代码:

    public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("1");list.add("2");list.add("3");for (String s : list) {if ("1".equals(s)) {list.remove(s);}}}

  定义了一个集合,存入了三个元素,然后在增强for循环中对元素进行删除,然后运行,毫无疑问地出现了ConcurrentModificationException(并发修改异常)。这也是经典面试题中所说,不能一边遍历集合一边删除元素,如果必须要这么做,需要使用迭代器

Exception in thread "main" java.util.ConcurrentModificationExceptionat java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)at java.util.ArrayList$Itr.next(ArrayList.java:851)at com.light.gulimall.product.web.ItemController.main(ItemController.java:41)

  下面我们从源码的角度对问题进行分析


二、问题分析

  增强型 For 循环是 For 循环的语法糖,经过编译后的class文件中,是这样:

    public static void main(String[] args) {ArrayList<String> list = new ArrayList();list.add("1");list.add("2");list.add("3");Iterator var2 = list.iterator();while(var2.hasNext()) {String s = (String)var2.next();if ("1".equals(s)) {list.remove(s);}}}

  我们跟踪进list.remove(s)这行代码,发现最终每次执行一次remove操作,AbstractList抽象类的成员变量modCount都会+1。
在这里插入图片描述  从modCount的注释上也可以看出,新增,删除等操作,都会导致这个变量的值增加:
在这里插入图片描述  再次观察报错时的堆栈信息,发现问题出现在java.util.ArrayList$Itr.next(ArrayList.java:851)java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901):
  第一个Itr.next,对应的是编译后class文件的
在这里插入图片描述  继续跟进,进入java.util.Iterator接口,选择如图的实现:
在这里插入图片描述  会发现在执行移动指针的的逻辑之前,先进入checkForComodification()方法,也就是先前报错信息中的Itr.checkForComodification
在这里插入图片描述  在checkForComodification()方法中会进行判断,将当前的modCountexpectedModCount进行比较,如果不一致就会抛出最开始的异常。
在这里插入图片描述  而expectedModCount是Itr的一个成员变量,它的值是modCount,并且后续不会对此变量的值进行更新,只在构造Itr对象时进行了初始化。
在这里插入图片描述  每次进行添加元素,删除元素时,modCount都会+1,而expectedModCount不会改变,必然两者不会相等,所以在移动指针时校验不通过,出现经典的ConcurrentModificationException(并发修改异常)。
在这里插入图片描述


三、问题解决

  通过上面的分析,想必已经对为什么会出现并发修改异常,有了一定的认识,那么如何避免这样的问题?答案是可以使用迭代器:

    public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("1");list.add("2");list.add("3");Iterator<String> it = list.iterator();while (it.hasNext()) {String element = it.next();it.remove();}System.out.println(list);}

  执行后没有发生异常,并且集合中的元素最终被清空,原因在于,使用了迭代器的remove() 方法,会在调用集合的remove()方法后,将最新的modCount重新赋值给expectedModCount,所以在下一次执行it.next()移动指针时,校验两者是否相等则不会抛出异常。
在这里插入图片描述

四、总结

  集合类中,modCount字段设计的目的就是为了标记修改的次数,从而保证快速失败的机制。子类可以自由选择是否使用这个字段。官方也是不推荐一边遍历集合,一边删除元素的操作。如果一定要,可以使用迭代器避免并发修改异常。

关键字:注册商标费用多少钱_查法人信息的系统_优化师_搜狗优化排名

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: