java迭代集合出现并发修改异常(ConcurrentModificationException)的原因以及解决方案
java迭代集合出现并发修改异常(ConcurrentModificationException)的原因以及解决方案
一. 什么时候会出现并发修改异常?
这里先看需求 : 定义一个集合,存储 唐僧,孙悟空,猪八戒,沙僧,遍历集合,如果遍历到猪八戒,往集合中添加一个白龙马
很显然要求我们先创建一个集合并进行迭代 , 当迭代到猪八戒,的时候插入白龙马
代码实现
public static void main(String[] args) {//需求:定义一个集合,存储 唐僧,孙悟空,猪八戒,沙僧,遍历集合,如果遍历到猪八戒,往集合中添加一个白龙马ArrayList<String> list = new ArrayList<>();list.add("唐僧");list.add("孙悟空");list.add("猪八戒");list.add("沙僧");Iterator<String> iterator = list.iterator();while(iterator.hasNext()){String element = iterator.next();if ("猪八戒".equals(element)){list.add("白龙马");}}System.out.println(list);}
运行后报错

这里报了一个ConcurrentModificationException 也就是并发修改异常
二. 产生原因
我们来进入源码分析一下
-
首先我们来进入 iterator() 方法 , 这里iterator() 是返回了了一个新对象也就是Itr() , 那我们再来看一下Itr()方法
public Iterator<E> iterator() {return new Itr();} -
Itr() , 光观察Itr()好像并没有发现异常的原因 , 那我们再看next()方法
private class Itr implements Iterator<E> {int cursor; // index of next element to returnint lastRet = -1; // index of last element returned; -1 if no suchint expectedModCount = modCount;// prevent creating a synthetic constructorItr() {}public boolean hasNext() {return cursor != size;} -
next() , 这里在运行next()的时候会先调用checkForComodification();方法那我们就先来查看这个方法
@SuppressWarnings("unchecked")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];} -
checkForComodification() , 很显然这里判断了modCount 与 expectedModCount是否相等 , 如果不相等则抛出throw new ConcurrentModificationException(); 也就是并发修改异常
modCount: 实际操作次数
expectedModCount:预期操作次数final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();} -
那么通过上面的分析我们就知道了产生问题的原因是什么 , 也就是modCount 与 expectedModCount并不相等
那是什么导致modCount 与 expectedModCount不相等的呢 ? 在代码中我们调用了一个add方法 , 那么add是否就是产生问题的原因
-
add() , 还是和刚才一样 , 进入add()底层源码我们来找一下原因
public boolean add(E e) {modCount++;add(e, elementData, size);return true;}到这里就一目了然了我们在调用add的时候会对modCount++ , 在modCount自增之后 , 我们再调用next()方法就会导致modCount 与 expectedModCount不相等 , 从而抛出异常
三. 解决方法
ArrayList中的方法:ListIterator listIterator()
public class Demo03Iterator {public static void main(String[] args) {//需求:定义一个集合,存储 唐僧,孙悟空,猪八戒,沙僧,遍历集合,如果遍历到猪八戒,往集合中添加一个白龙马ArrayList<String> list = new ArrayList<>();list.add("唐僧");list.add("孙悟空");list.add("猪八戒");list.add("沙僧");//Iterator<String> iterator = list.iterator();ListIterator<String> listIterator = list.listIterator();while(listIterator.hasNext()){String element = listIterator.next();if ("猪八戒".equals(element)){listIterator.add("白龙马");}}System.out.println(list);}
}
相关文章:
java迭代集合出现并发修改异常(ConcurrentModificationException)的原因以及解决方案
java迭代集合出现并发修改异常(ConcurrentModificationException)的原因以及解决方案 一. 什么时候会出现并发修改异常? 这里先看需求 : 定义一个集合,存储 唐僧,孙悟空,猪八戒,沙僧,遍历集合,如果遍历到猪八戒,往集合中添加一个白龙马 很显然要求我们先创建一个集合并进行…...
BGP选路之Local Preference
原理概述 当一台BGP路由器中存在多条去往同一目标网络的BGP路由时,BGP协议会对这些BGP路由的属性进行比较,以确定去往该目标网络的最优BGP路由。BGP首先比较的是路由信息的首选值(PrefVal),如果 PrefVal相同,就会比较本…...
WEB渗透信息收集篇--IP和端口信息
WEB渗透信息收集篇--域名信息-CSDN博客 WEB渗透信息收集篇--网站架构和指纹识别-CSDN博客 WEB渗透信息收集篇--人员信息-CSDN博客 WEB渗透信息收集篇--其他信息-CSDN博客 一、ASN ASN Tool - MxToolBox ASN通常指的是"自…...
国内微短剧系统平台抖音微信付费小程序app开发源代码交付
微短剧作为当下热门的内容,结合抖音平台的广泛用户基础,开发微短剧付费小程序APP具有显著的市场潜力,用户对于短剧内容的需求旺盛,特别是在言情、总裁、赘婿等热门题材方面,接下来给大家普及一下微短剧小程序系统。 顺…...
Java语言程序设计基础篇_编程练习题**15.19 (游戏:手眼协调)
**15.19 (游戏:手眼协调) 请编写一个程序,显示一个半径为10像素的实心圆,该圆放置在面板上的随机位置,并填充随机的顔色,如图15-29b所示。单击这个圆时,它会消失,然后在另一个随机的位置显示新的随机颜色的…...
学习记录day16—— 数据结构 双向链表 循环链表
双向链表 1、概念 1)就是从任意一个节点既能存储其前驱节点,又能存储后继节点 2)结构体中增加一个指向前驱节点的指针 //定义数据类型 typedef int datatype;//定义节点类型 typedef struct Node {union {int len;datatype data;};struct Node *prio; …...
Air780EP模块 AT开发-MQTT接入OneNET移动物联网平台应用指南
应用概述 使用AT方式通过MQTT协议连接onenet studio。官网地址:https://open.iot.10086.cn/ 材料准备 Air780EP(V)开发板一套,包括天线SIM卡,USB线。 PC电脑,串口工具 在onenet上创建产品 打开OneNET官网,进入控制…...
HOST处理器预读PCI设备
在PCI(Peripheral Component Interconnect)总线规范中,MRL(Memory Read Line)和MRM(Memory Read Multiple)是两种读取存储器地址空间的总线事务类型。 MRL(Memory Read Line…...
【Ansible】通过role角色部署lnmp架构
目录 一.roles概述 1.roles角色 2.roles的目录层次 2.1.roles 内各目录含义解释 二.实操 1.部署nginx 2.部署MySQL 3.部署php 4.编写测试文件 三.总结 一.roles概述 1.roles角色 可以把playbook剧本里的每个play看作为一个角色,将每个角色要用到的文件、…...
springboot给属性赋值的两种方式(yaml与properties)
一,介绍 在Spring Boot中,配置文件是用来设置应用程序的各种参数和操作模式的重要部分。Spring Boot支持两种主要类型的配置文件:properties文件和YAML 文件。这两种文件都可以用来定义相同的配置,但它们在格式和表达能力上有所不…...
20240725 每日AI必读资讯
🚀最强开源模型来了!Llama3.1以405B参数领先GPT-4o - Llama3.1以405B参数领先GPT-4o和Claude3.5Sonnet,在性能上实现超越。 - Meta大幅优化训练栈,扩展模型算力规模至16000个H100GPU,提高性能。 - Llama3.1具有上下文长度扩展、…...
17_高级进程间通信 UNIX域套接字1
非命名的UNIX域套接字 第1个参数domain,表示协议族,只能为AF_LOCAL或者AF_UNIX; 第2个参数type,表示类型,只能为0。 第3个参数protocol,表示协议,可以是SOCK_STREAM或者SOCK_DGRAM。用SOCK_STR…...
大型语言模型的生物医学知识图优化提示生成
大型语言模型的生物医学知识图优化提示生成 https://arxiv.org/abs/2311.17330 https://github.com/BaranziniLab/KG_RAG 大型语言模型的生物医学知识图优化提示生成 摘要 KG-RAG框架,较好的结合了生物医学知识图谱SPOKE和LLM的优势。SPOKE是一个开放知识图谱&…...
winform datagrid 全部勾选
如果我们想要进行全选或全部取消,在数据较多的情况下,这种方法显然特别繁琐。怎么办呢? 当然是加以一个全选按钮了,选中全选按钮则全选,否则取消。笔者本想在红色圆圈位置添加全选复选框的,那样看起来更加…...
从 NextJS SSRF 漏洞看 Host 头滥用所带来的危害
前言 本篇博文主要内容是通过代码审计以及场景复现一个 NextJS 的安全漏洞(CVE-2024-34351)来讲述滥用 Host 头的危害。 严正声明:本博文所讨论的技术仅用于研究学习,旨在增强读者的信息安全意识,提高信息安全防护技能…...
LC617-合并二叉树
文章目录 1 题目描述2 思路优化代码完整输入输出 参考 1 题目描述 https://leetcode.cn/problems/merge-two-binary-trees/description/ 给你两棵二叉树: root1 和 root2 。 将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另…...
深入解析:端到端目标检测模型的奥秘
深入解析:端到端目标检测模型的奥秘 在人工智能领域,计算机视觉任务一直是研究的热点之一。目标检测作为计算机视觉中的核心问题,其重要性不言而喻。端到端的目标检测模型,以其高效的性能和简洁的架构,逐渐成为研究和…...
xmind--如何快速将Excel表中多列数据,复制到XMind分成多级主题
每次要将表格中的数据分成多级时,只能复制粘贴吗 快来试试这个简易的方法吧 这个是原始的表格,分成了4级 步骤: 1、我们可以先按照这个层级设置下空列(后买你会用到这个空列) 二级不用加、三级前面加一列、四级前面加…...
在 Android 上实现语音命令识别:详细指南
在 Android 上实现语音命令识别:详细指南 语音命令识别在现代 Android 应用中变得越来越普遍。它允许用户通过自然语言与设备进行交互,从而提升用户体验。本文将详细介绍如何在 Android 上实现语音命令识别,包括基本实现、带有占位槽位的命令处理,以及相关的配置和调试步骤…...
怎么理解FPGA的查找表与CPLD的乘积项
怎么理解 fpga的查找表 与cpld的乘积项 FPGA(现场可编程门阵列)和CPLD(复杂可编程逻辑器件)是两种常见的数字逻辑器件,它们在内部架构和工作原理上有着一些显著的区别。理解FPGA的查找表(LUT,L…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...
