并发修改异常 ConcurrentModificationException详解

news/2024/11/14 15:16:30/文章来源:https://www.cnblogs.com/zhuzhuya/p/18353835

并发修改异常 ConcurrentModificationException详解

  • 异常产生原因:并发修改异常指的是在并发环境下,当方法检测到对象的并发修改,但不允许这种修改时,抛出该异常。

  • 异常抛出在ArrayList类中的checkForComodification()方法中。

  • checkForComodification()方法实际上就是当modCount 变量值不等于expectedModCount变量值时,就会触发此异常。

  • modCount :AbstractList类中的一个成员变量,由于ArrayList继承自AbstractList,所以ArrayList中的modCount变量也继承过来了。

  • expectedModCount:是ArrayList中内部类Itr的一个成员变量,当我们调用iterater()获取迭代器方法时,会创建内部类Itr的对象,并给其成员变量expectedModCount赋值为ArrayList对象成员变量的值modCount【预期修改次数】。

  • 查看ArrayList的源码可知,modCount 初始值为0, 每当集合中添加一个元素或者删除一个元素时,modCount变量的值都会加一,表示集合中结构修改次数多了一次

解决方案

当用迭代器遍历元素时,集合不能修改,但是迭代器可以修改

由上图可知,modCount和expectedModCount会一直相等,所以不会抛出异常

举例:使用List集合存储字符串元素,使用迭代器遍历,遍历的时候,如果遇到"java",就向集合中添加一个元素"shujia"

import java.util.ArrayList;
import java.util.ListIterator;
public class ListDemo1 {public static void main(String[] args) {ArrayList l2 = new ArrayList();l2.add("hello");l2.add("java");l2.add("world");l2.add("hello");System.out.println(l2);System.out.println("===============");ListIterator listIterator = l2.listIterator();while (listIterator.hasNext()){Object o = listIterator.next();String s = (String) o;  //下转型。因为Object类没有equals()方法if (s.equals("java")){listIterator.add("shujia"); //List迭代器追加}}System.out.println(l2);}
}


拓展:当要删除的元素在集合中的倒数第二个元素的时候,删除元素不会产生并发修改异常。
原因:因为在调用hasNext()方法的时候,cursor = size是相等的,hasNext()方法会返回false, 所以不会执行next()方法,也就不会调用checkForComodification()方法,就不会发生并发修改异常。

小结论:

  1. 迭代器调用remove()方法删除元素,底层还是调用的集合的删除元素的方法;
  2. 在调用remove()方法后,都会将modCount的值赋值给expectedModCount,保证了它两的值永远都是相等的,所以也就不会产生并发修改异常;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/781402.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024暑假集训测试21

前言比赛链接。T1 写得和正解差不多但少了个细节炸 long long 了;T2 只会 \(n^3\) 的本来只有 \(50pts\),但考虑出题人大概率会搞一个 \(n\) 越大 \(T\) 越小,所以对于 \(n\) 很大的直接 \(rand\) 正确率还是有的,所以获得了 \(80pts\);T3 不会;T4 没有和 \(n\) 取 \(\m…

线性整数规划的三道经典例题

目录一、背包问题1.模型建立2.代码实现二、指派问题1.模型建立2.代码实现(1)输入目标函数系数(2)输入不等式约束(3)输入等式约束(4)调用函数求解三、钢管切割问题1.问题分析2.模型建立(1)利用枚举法找到料头小于等于0.9的切割方法(2)得到目标函数与约束3.代码实现(…

qt 设计界面中 scrollarea等子控件内部widget布局方法

默认这个右键布局里的选项为灰色,点不了,可以先往widget中拖一个按钮进去,然后再右键布局,然后再把按钮删掉,就相当于在设计界面 就设置好布局了

DataWhale-2024夏令营第四期-从零入门AI生图原理实践-学习笔记

DataWhale-2024夏令营第四期-从零入门AI生图原理&实践-学习笔记 Datawhale (linklearner.com)学习链接 AI生图基础知识 一、文生图(Text-to-Image Generation)历史随着深度学习的发展,近些年来越来越多的AI生图效果通过大语言模型得到了一定的提升。文生图的历史:文生图的…

036.Vue3入门,组件的生命周期

1、App.vue代码如下:<template><div><h3>主页面</h3><button @click="change">改变</button></div> </template><script> export default {beforeCreate() { console.log(beforeCreate) },created() { conso…

035.Vue3入门,使用具名插槽Slot中,同时显示主页面和多个插槽页面内容

1、App.vue代码如下:<template><div><h3>主页面</h3><Slot001><template #s1="slotProps"><h4>{{ msg }} === {{ slotProps.msg1 }}</h4></template><template #s2="slotProps"><h4>{…

CF1264E Beautiful League 题解

CF1264E 你有一张竞赛图,给你竞赛图中 \(m\) 条边的方向,让你对于没有给定的边确定方向使得整张图的三元环个数最多 \(n \leq 50, m \leq \frac{(n-1)n}{2}\)费用流好题三元环是一个非常难考虑的东西,我们考虑求他的补集:不是三元环的个数最少我们发现不是三元环的情况是存…

一步一步微调小模型

本文记录一下,使用自顶向下的编程法一步步编写微调小语言模型的代码。微调一个语言模型,本质上是把一个已经预训练过的语言模型在一个新的数据集上继续训练。那么一次微调模型的任务,可以分为下面三个大个步骤(不包含evaluation):加载已经预训练好的模型和新的数据集 预处…

最全MySQL面试20题和答案(三)

接第二期的MySQL面试二十题,这是之后的20题!视图 1. 为什么要使用视图?什么是视图?为了提高复杂 SQL 语句的复用性和表操作的安全性,MySQL 数据库管理系统提供了视图特性。所谓视图,本质上是一种虚拟表,在物理上是不存在的,其内容与真实的表相似,包含一系列带有名称的…

实战-行业攻防应急响应

实战-行业攻防应急响应简介: 服务器场景操作系统 Ubuntu 服务器账号密码:root/security123 分析流量包在/home/security/security.pcap 相关jar包在/home/security/ruoyi/ruoyi-admin.jar 应急主机: 192.168.0.211 网关: 192.168.0.1/24 其它傀儡机: 段内 本次环境来自某次行…

033.Vue3入门,多个插槽Slot的命名调用和#号简写

1、App.vue代码如下:<template><div><h3>插槽学习</h3><Slot001><!-- 插槽1--><template v-slot:s2><p>{{ msg1 }}</p></template><!-- 插槽2--><template #s1><p>{{ msg2 }}</p>…

个人Blog的第一篇博文

个人Blog的第一篇博文正式加入"博客园"大家庭了,希望以后可以一直坚持下去欸。