You need to enable JavaScript to run this app. 为何克隆ArrayList后调用joinToString仍抛出ConcurrentModificationException
优惠活动
大模型
产品
解决方案
定价
更多

为何克隆ArrayList后调用joinToString仍抛出ConcurrentModificationException

异常成因说明

ArrayList的clone()方法本身没有任何同步保护机制,不是原子操作,这是你遇到偶发异常的核心原因:

  • 你在UI线程执行clone()操作时,后台线程同时在修改原集合的结构(增删元素),而clone()执行过程中需要读取原集合的底层数组、元素数量size、修改计数modCount等内部状态。
  • 若后台的修改操作恰好处于中间状态(比如已经更新了modCount、但还没完成元素的插入和size的更新,或者正在移动数组元素完成删除操作),此时clone()读取到的就是一组不一致的内部状态,生成的克隆对象本身就存在结构错误。
  • 尽管标准JDK中ArrayList的clone()会把新集合的modCount重置为0,但Android平台对ArrayList的实现有定制,加上极端时序下状态错乱,会导致克隆得到的集合modCount和实际结构不匹配。后续调用joinToString()时,方法底层会创建迭代器遍历集合,迭代器的fail-fast机制检测到modCount不符合预期,就会抛出ConcurrentModificationException。
补充方案

如果要保留克隆的实现逻辑,只需要在克隆时对原集合加锁,保证克隆操作全程原集合不会被修改即可:

val textLines = synchronized(globalTextLineArray) {
    globalTextLineArray.clone() as ArrayList<String>
}
myTextView.text = textLines.joinToString("\n")

内容的提问来源于stack exchange,提问作者user2808624

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 19:42:04