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

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 属性。

相关文章:

  • Unity开发者快速认识Unreal 的BluePrint
  • leetcode--两数之和 三数之和
  • 121.在 Vue3 中使用 OpenLayers 实现去掉鼠标右键默认菜单并显示 Feature 信息
  • 通信与推理的协同冲突与架构解耦路径
  • Java 中 XML 处理工具类详解
  • Scribe: 一个非常方便的操作文档编写工具
  • Linux file 命令详解
  • L1-7、Prompt 的“调试技巧”
  • 文件操作和IO(上)
  • L1-6、Prompt 与上下文的关系[特殊字符]
  • metasploit(2)生成dll木马
  • 基于 Spring Boot实现的图书管理系统
  • 龙虎榜——20250422
  • PyTorch与自然语言处理:从零构建基于LSTM的词性标注器
  • JavaScript的JSON处理Map的弊端
  • Spring Boot 应用优雅关闭
  • FLV 与 MP4 格式深度剖析:结构、原理
  • 【前端】【业务场景】【面试】在网页开发中,如何优化图片以提高页面加载速度?解决不同设备屏幕适配问题
  • 进阶篇 1:超越基准 - 指数平滑 (ETS) 模型详解
  • http通信之axios vs fecth该如何选择?
  • 山西省援疆前方指挥部总指挥刘鹓已任忻州市委副书记
  • 山东一季度GDP为23466亿元,同比增长6.0%
  • 聚焦“共赢蓝色未来” “海洋命运共同体”上海论坛举行
  • “听公交时听一听”,上海宝山街头遍布“有声图书馆”
  • 上海市委财经委会议分析研判当前经济运行情况,调度部署下阶段重点工作
  • 电商平台全面取消“仅退款”:电商反内卷一大步,行业回归良性竞争