abstractsequentiallist的listiterator遵循fail-fast机制,通过继承的modcount与expectedmodcount比对实现并发修改检测,遍历时调用next()等方法前均执行checkforcomodification(),不一致则抛concurrentmodificationexception。

AbstractSequentialList 的 ListIterator 同样遵循 fail-fast 机制,但它的实现逻辑与 ArrayList 中基于数组索引的 Itr 不同——它依赖链表结构的遍历特性,仍通过 modCount 和 expectedModCount 配合完成并发修改检测。
modCount 在 AbstractSequentialList 中的作用
AbstractSequentialList 继承自 AbstractList,因此也继承了 modCount 字段。每次调用结构性修改方法(如 add(int, E)、remove(int)、clear())时,modCount 自增。该字段是 fail-fast 的统一判断依据,不因底层是数组还是链表而改变。
ListIterator 创建时捕获预期状态
当调用 listIterator(int index) 时,AbstractSequentialList 返回的是其子类(如 LinkedList)提供的 ListIterator 实现(例如 LinkedList.ListItr)。该迭代器在构造时会记录当前 modCount 值为 expectedModCount:
- 即使遍历过程是逐节点游走(而非随机索引访问),只要底层链表被结构性修改,
modCount就会变化 - 每次调用
next()、previous()、set(E)或remove()前,都会执行checkForComodification() - 该检查逻辑与 ArrayList.Itr 完全一致:若
modCount != expectedModCount,立即抛出ConcurrentModificationException
结构性修改触发检测的典型场景
以下操作会导致 fail-fast 异常,无论是否多线程:
- 在 ListIterator 遍历过程中,直接调用 list 的
add(E)或remove(Object) - 同一 list 上多个 ListIterator 并发操作,其中一个调用了结构性修改方法
- 单线程中,先获取 ListIterator,再用 list 自身的
remove(int)删除元素,随后继续调用next()
与 Fail-Safe 的关键区别
AbstractSequentialList 及其典型实现 LinkedList 不提供快照副本机制。它的 ListIterator 操作始终作用于原始链表节点,且不复制数据——这意味着:
- 读写共用同一份结构,保证内存高效,但牺牲了遍历时的修改自由度
- 无法像 CopyOnWriteArrayList 那样容忍遍历中修改,也不支持弱一致性读取
- fail-fast 是一种检测性保障,不是同步控制;它不阻止修改发生,只确保错误行为被及时发现
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











