当前位置: 首页 > ds >正文

Size of map written was 1, but number of entries written was 0. 异常分析

背景

一个 Kafka 连接测试类,发送数据时报了上面的异常:

java.util.ConcurrentModificationException: Size of map written was 1, but number of entries written was 0. at org.apache.avro.generic.GenericDatumWriter.writeMap(GenericDatumWriter.java:178)

异常原因分析

java.util.ConcurrentModificationException 异常通常在遍历集合(如 HashMap、ArrayList 等)时,直接修改集合的结构(例如添加或删除元素)而引发。

具体到问题描述中的错误信息:“Size of map written was 1, but number of entries written was 0”,这表明在遍历 HashMap 时发生了并发修改异常。

  1. 遍历过程中修改集合:在使用增强型 for 循环或 Iterator 遍历 HashMap 时,如果直接调用 map.remove(key) 方法来删除元素,会导致 ConcurrentModificationException 异常。这是因为 Iterator 在遍历时会检查集合的 modCount(修改次数),如果在遍历过程中集合被修改,modCount 会发生变化,从而触发异常。
  2. 单线程环境下的并发修改:即使在单线程环境中,如果在遍历集合时直接修改集合的结构,也会抛出 ConcurrentModificationException 异常。这是因为 Iterator 在遍历时依赖于集合的初始状态,任何结构上的修改都会导致异常。

解决方案

使用 Iterator 的 remove 方法:在遍历 HashMap 时,应该使用 Iterator 提供的 remove 方法来删除元素,而不是直接调用 map.remove(key)。这样可以确保 Iterator 能够正确地更新 expectedModCount,从而避免 ConcurrentModificationException 异常。

诡异问题

这个问题发生的很诡异,Map 对象是一个测试 Kafka 转发的静态成员变量,然后在一个 init 方法中存入了一个固定的值,代码如下:

private static Map<String, String> data = new HashMap<>(1);public void init() {data.put("DATA", "test");
}

诡异的是,整个类中就只有这个方法被调用一次的 put 后就没有写该 Map 对象的地方了,理论上不应该出现 Map 的 size 读取和 iterator 迭代器遍历后的总数不一致的情况的。

即使是碰巧两个类同时执行了 put 操作,但是 HashMap 类的 put 操作同一个 key 的时候应该不涉及到 remove 操作才对。

启示录

类的私有静态成员变量存在并发问题么?答案是肯定的,静态私有成员变量被所有该类的实例对象共享的,所以存在并发问题。

因此编码时应该理清楚类的成员变量的特点,确定所有实例共享的属性可以设计为 static同时必须在对该变量的操作函数中做好并发控制。 否则,定义为类成员变量就可以了,可以避免本文这种诡异的问题。

而本例中定义的 Map 成员变量实际是一个全局且初始化一次的变量,可以放在静态代码块中初始化,或者直接定义为非 static 属性。

http://www.xdnf.cn/news/1299.html

相关文章:

  • 进阶篇 第 7 篇 (终章):融会贯通 - 多变量、模型选择与未来之路
  • 数据可视化--数据探索性分析
  • 数据库MySQL学习——day1(创建表与数据类型)
  • win10中打开python的交互模式
  • Ubuntu 22.04安装IGH
  • CRM系统的功能有哪些?CRM系统功能指南
  • RenderDoc 使用介绍
  • STL C++详解——priority_queue的使用和模拟实现 堆的使用
  • 高新技术申报有哪些潜在风险?如何避免?
  • AI 模型可靠性危机:DeepSeek 输出异常的技术归因与防范实践
  • 算力网络有关论文自用笔记(2)
  • L1-5、Prompt 写作中的常见误区
  • 公路路面病害检测
  • 【AI】SpringAI 第五弹:接入千帆大模型
  • 通过AI工具或模型创建PPT的不同方式详解,结合 Assistants API、DALL·E 3 等工具的功能对比及表格总结
  • 用红黑树封装出set和map
  • Pandas与NumPy高效结合使用指南
  • 利用内联注解析释差异构造多语言sql注入 -- b01lers CTF defense-in-depth
  • Linux从入门到荒废-查找文件中重复的数据
  • SSH 互信被破坏能导致 RAC 异常关闭吗
  • AI大模型:(二)2.3 预训练自己的模型
  • 管理+技术”双轮驱动工业企业能源绿色转型
  • 人工智能赋能医疗影像诊断:开启精准医疗新时代
  • Java 中 == 和 equals() 的区别
  • Pytorch实用教程(一):torch.compile计算提速
  • Linux内核之文件驱动随笔
  • 【Git】fork 和 branch 的区别
  • 狄拉克梳状函数的傅里叶变换
  • 联易融与中交第一航务工程局深化合作交流,共探创新发展新路径
  • 模型 替罪羊效应