JonLv 的个人博客   记录精彩的程序人生

Open Source, Open Mind,
Open Sight, Open Future!

标签: Java (22)

ArrayList 扩容相关思考

本文针对 Java ArrayList 源码中的三个常见疑问展开分析:

1. 减法比较 vs 直接比较

grow() 方法中使用 newCapacity - MAX_ARRAY_SIZE > 0 而非直接比较,是为了处理整数溢出的极端情况。

  • 直接比较 :若 newCapacity 溢出为负数(如扩容过大),会错误跳过容量校验逻辑。
  • 减法比较 :溢出后的结果可能触发 hugeCapacity() 方法,通过检查 minCapacity 是否溢出(负数)抛出 OutOfMemoryError,确保异常情况被捕获。

2. MAX_ARRAY_SIZE 设为 Integer.MAX_VALUE - 8 的原因

  • 预留元数据空间 :避免因 JVM 对象头(类型指针、数组长度等)占用内存导致分配失败。
  • 兼容性保障 :不同 JVM 实现可能对数组元数据有不同要求,预留 8 字节增强通用性。
  • 极端突破机制hugeCapacity() 方法仍允许在安全条件下分配至 Integer.MAX_VALUE,平衡安全性与灵活性。

3. modCount 的作用与 Fail-Fast 机制

  • 功能 :记录集合结构性修改次数(如增删元素),用于迭代时检测并发修改。
  • 实现原理 :迭代器保存初始 expectedModCount,每次操作前校验与 modCount 是否一致,不一致则抛出 ConcurrentModificationException
  • 应用场景 :防止单线程迭代时误改集合,或暴露多线程并发修改问题,辅助开发者快速定位逻辑错误。

核心总结 :通过源码级分析,揭示了 ArrayList 在容量计算、内存分配安全边界及并发修改检测中的设计权衡,体现了 Java 集合框架对稳定性、兼容性和异常处理的细致考量。

记一次Druid连接池关闭异常问题 有更新!

文章描述了在一个项目中引入ClickHouse数据库后出现的异常情况,具体表现为Bean注销异常和数据连接获取失败异常。通过排查发现问题根源是MySQL和ClickHouse两个数据源设置了相同的name属性,导致在销毁连接池时发生错误。解决方法是让数据源自动生成name属性,避免重名导致连接池关闭的问题。文章总结了在配置多数据源时需要小心连接池配置,尤其是对于name属性的设置。

记一次mybatis与mybatisplus及mysql与cilickhouse共存遇到的问题 有更新!

在维护一个老项目时,考虑引入Mybatis-plus作为持久层,但在使用easy-code生成模板信息后遇到了Invalid bound statement异常。解决方案包括修改XML路径及实体别名映射配置,手动设置SqlSessionFactory为MybatisSqlSessionFactoryBean,并注意设置主键ID的生成方式。

同时,由于项目涉及日志记录,需要对日志存储进行改造,将后续日志请求落库到Clickhouse中。为此,进行了Clickhouse数据源和MySQL数据源的配置,使用Mybatis-plus增强的MybatisSqlSessionFactoryBean,同时集成分页插件。整体改造涉及持久层、数据源配置和日志存储,以适应项目的新需求和技术栈更新。