From 2839f2b27ba19c95e370f3b00515e2f2292acbba Mon Sep 17 00:00:00 2001 From: Guide Date: Thu, 9 Apr 2026 16:06:54 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=E5=A2=9E=E5=BC=BA=20f?= =?UTF-8?q?or=20=E5=BE=AA=E7=8E=AF=E4=B8=AD=20Iterator=20fail-fast=20?= =?UTF-8?q?=E6=9C=BA=E5=88=B6=E7=9A=84=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原描述错误地声称 Iterator 工作在独立线程中并持有 mutex 锁, 实际机制是通过 modCount/expectedModCount 计数器比较实现 fail-fast。 同时修正了 Iterator.remove() 的说明。 Closes #2818 --- docs/java/basis/syntactic-sugar.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/java/basis/syntactic-sugar.md b/docs/java/basis/syntactic-sugar.md index 615b008e43e..e0b15493d2b 100644 --- a/docs/java/basis/syntactic-sugar.md +++ b/docs/java/basis/syntactic-sugar.md @@ -861,9 +861,9 @@ for (Student stu : students) { 会抛出`ConcurrentModificationException`异常。 -Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出`java.util.ConcurrentModificationException`异常。 +这里涉及集合的 **fail-fast(快速失败)** 机制。以 `ArrayList` 为例,其内部维护了一个 `modCount` 计数器,每次对集合结构进行修改(如添加、删除)时都会递增该计数器。当创建 `Iterator` 时,会将当前的 `modCount` 记录为 `expectedModCount`。在每次调用 `next()` 时,`Iterator` 都会检查 `modCount` 是否等于 `expectedModCount`,如果不等,说明集合在遍历期间被其他方式修改了,就会抛出`java.util.ConcurrentModificationException`异常。 -所以 `Iterator` 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 `Iterator` 本身的方法`remove()`来删除对象,`Iterator.remove()` 方法会在删除当前迭代对象的同时维护索引的一致性。 +所以 `Iterator` 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 `Iterator` 本身的方法`remove()`来删除对象,`Iterator.remove()` 方法会在删除元素后同步更新 `expectedModCount`,从而避免触发该异常。 ## 总结