java - 为什么 Vector 方法 Iterator 和 ListIterator 快速失败

标签 java collections

根据 http://download.oracle.com/javase/1.4.2/docs/api/java/util/Vector.html

The Iterators returned by Vector's iterator and listIterator methods are fail-fast: if the Vector is structurally modified at any time after the Iterator is created, in any way except through the Iterator's own remove or add methods, the Iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the Iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future. The Enumerations returned by Vector's elements method are not fail-fast. Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs

你能给我一个例子来验证上面的语句集吗?我仍然不清楚 vector 的方法 Iterator 和 ListIterator 的快速失败行为。 困惑:-((

最佳答案

if the Vector is structurally modified at any time after the Iterator is created, in any way except through the Iterator's own remove or add methods, the Iterator will throw a ConcurrentModificationException.

这是一个例子:

import java.util.*;

public class Test {

    public static void main(String[] args) {
        List<String> strings = new Vector<String>();

        strings.add("lorem");
        strings.add("ipsum");
        strings.add("dolor");
        strings.add("sit");

        int i = 0;

        Iterator<String> iter = strings.iterator();
        while (iter.hasNext()) {
            System.out.println(iter.next());

            // Modify the list in the middle of iteration.
            if (i++ == 1)
                strings.remove(0);
        }
    }
}

输出:

lorem
ipsum
Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
    at java.util.AbstractList$Itr.next(AbstractList.java:343)
    at Test.main(Test.java:18)

该程序执行以下操作:

  1. 创建一个 Vector 并获取一个迭代器
  2. 调用 next() 两次。
  3. 修改 vector (通过删除第一个元素)
  4. 再次调用next()(在 vector 被修改之后)
  5. 这会导致抛出 ConcurrentModificationException

由于 Java 的 for-each 循环依赖于迭代器,这些结构也可能抛出 ConcurrentModificationExceptions。解决方案是在迭代之前制作列表的副本(因此您迭代副本)或使用例如 CopyOnWriteArrayList像这样:

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

public class Test {

    public static void main(String[] args) {
        List<String> strings = new CopyOnWriteArrayList<String>();

        strings.add("lorem");
        strings.add("ipsum");
        strings.add("dolor");
        strings.add("sit");

        int i = 0;

        Iterator<String> iter = strings.iterator();
        while (iter.hasNext()) {
            System.out.println(iter.next());

            // Modify the list in the middle of iteration.
            if (i++ == 1)
                strings.remove(0);
        }
    }
}

输出:

lorem
ipsum
dolor
sit

关于java - 为什么 Vector 方法 Iterator 和 ListIterator 快速失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4479554/

相关文章:

java - Apache Spark 行从时间戳到日期转换异常

java - 实现几个签名冲突的接口(interface)

java - 对 List 对象内的 List 进行排序

java - 将 Ckfinder 与 ckeditor 和 JSP 结合使用

java - RMI-REGISTRY 的 RMI 位置

java - 如何在普通java项目中使用maven项目jar

java - Collections.unmodifiableList 是否存在性能风险?

java - Hibernate 级联类型删除父级

mongodb - 从mongodb中的三个集合中获取结果

java - 与手动搜索列表相比,Collections.binarySearch 的性能如何?