You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中重写LinkedList迭代器时如何检测并发修改异常?

在自定义双向链表迭代器中实现并发修改异常检测

要在自定义迭代器中检测并发修改异常,核心是使用fail-fast机制——通过维护「链表修改计数器」和「迭代器预期修改计数器」的配对关系来实现,这也是Java标准集合(如ArrayList、LinkedList)的通用做法。

具体实现步骤:

  1. 在双向链表类中添加修改计数器
    在链表类中声明一个modCount成员变量,每次执行会改变链表结构的操作(比如add、remove、clear)时,将modCount自增,记录链表被修改的次数。

  2. 在迭代器中维护预期修改计数器
    创建迭代器时,将内部的expectedModCount初始化为当前链表的modCount值,相当于保存一份迭代器创建时的链表修改状态快照。

  3. 每次迭代操作前检查计数器一致性
    在迭代器的next()、hasNext()方法中,先检查modCount和expectedModCount是否相等。如果不等,说明迭代器创建后链表被外部线程或其他迭代器修改了,直接抛出ConcurrentModificationException。

  4. 迭代器自身修改时同步计数器
    如果迭代器实现了remove()方法(合法的迭代器内修改),执行完移除操作后,需要同步更新modCount和expectedModCount,避免触发异常。

修改后的完整代码示例

双向链表类核心部分

public class DoublyLinkedList<T> {
    private Node<T> head;
    private Node<T> tail;
    // 记录链表结构修改次数的计数器
    private int modCount = 0;

    // 示例:添加元素的方法,每次修改结构后自增modCount
    public void add(T data) {
        Node<T> newNode = new Node<>(data);
        if (head == null) {
            head = newNode;
            tail = newNode;
        } else {
            tail.next = newNode;
            newNode.prev = tail;
            tail = newNode;
        }
        modCount++; // 结构修改,计数器自增
    }

    // 示例:移除元素的方法,同样需要自增modCount
    public boolean remove(T data) {
        Node<T> current = head;
        while (current != null) {
            if (data.equals(current.data)) {
                if (current.prev != null) {
                    current.prev.next = current.next;
                } else {
                    head = current.next;
                }
                if (current.next != null) {
                    current.next.prev = current.prev;
                } else {
                    tail = current.prev;
                }
                modCount++;
                return true;
            }
            current = current.next;
        }
        return false;
    }

    // 内部节点类
    private static class Node<T> {
        T data;
        Node<T> prev;
        Node<T> next;

        Node(T data) {
            this.data = data;
        }
    }

    // 重写的iterator方法,包含并发检测逻辑
    @Override
    public Iterator<T> iterator() {
        return new Iterator<T>() {
            private Node<T> trav = head;
            // 初始化预期修改计数器为当前链表的modCount
            private int expectedModCount = modCount;

            @Override
            public boolean hasNext() {
                checkForComodification();
                return trav != null;
            }

            @Override
            public T next() {
                checkForComodification();
                if (!hasNext()) {
                    throw new NoSuchElementException();
                }
                T data = trav.data;
                trav = trav.next;
                return data;
            }

            // 可选:实现迭代器的remove方法
            @Override
            public void remove() {
                if (trav == head) {
                    throw new IllegalStateException("无法移除未访问的元素");
                }
                Node<T> toRemove = trav.prev;
                if (toRemove.prev != null) {
                    toRemove.prev.next = toRemove.next;
                } else {
                    head = toRemove.next;
                }
                if (toRemove.next != null) {
                    toRemove.next.prev = toRemove.prev;
                } else {
                    tail = toRemove.prev;
                }
                // 同步计数器,避免触发异常
                modCount++;
                expectedModCount = modCount;
            }

            // 检查并发修改的私有工具方法
            private void checkForComodification() {
                if (modCount != expectedModCount) {
                    throw new ConcurrentModificationException();
                }
            }
        };
    }
}

关键说明

  • fail-fast的局限性:这种机制是一种快速检测手段,不能保证100%检测到所有并发修改(比如在多线程环境下的极端情况),但足以应对绝大多数单线程和常规多线程场景下的非安全修改。
  • 合法修改的处理:只有迭代器自身的remove()操作不会触发异常,其他外部修改(比如直接调用链表的add/remove)都会被检测到。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 03:01:00