ArrayList.Itr#next()什么时候会在这一行抛出ConcurrentModificationException?

时间:2016-08-24 18:30:32

标签: java arraylist iterator

这个问题是关于JDK 1.8.0_74的。该课程为java.util.ArrayList$Itr。当调用ArrayList#iterator()方法时,将返回此(内部)类的实例。具体来说,我的问题是next()上的Itr方法:

850        public E next() {
851            checkForComodification();
852            int i = cursor;
853            if (i >= size)
854                throw new NoSuchElementException();
855            Object[] elementData = ArrayList.this.elementData;
856            if (i >= elementData.length)
857                throw new ConcurrentModificationException();
858            cursor = i + 1;
859            return (E) elementData[lastRet = i];
860        }

我理解第851行checkForComodification调用的基本原理[1]。我也理解第853行的(i >= size)检查[2]。

但是,第856行检查if (i >= elementData.length)的情况是什么?

在单线程代码中,我无法通过第{87行上的ConcurrentModificationException 使某些代码失败。

[1]:迭代器创建失败后的结构修改:

static void coMod() {
        ArrayList<Integer> list = new ArrayList<>(4);
        list.add(1);
        list.add(2);
        Iterator<Integer> itr = list.iterator();
        list.remove(0); //structural modification after iterator creation
        if (itr.hasNext()) {
            System.out.println("wait, there's more!");
            itr.next(); // modification while iterating -- 
                        // fails at java.util.ArrayList$Itr.next(ArrayList.java:851)
        }
    }

[2]:迭代器到达结束后失败

static void noHasNext() {
    ArrayList<Integer> list = new ArrayList<>(4);
    Iterator<Integer> itr = list.iterator();
    itr.next(); // unguarded next call -- 
                // fails at java.util.ArrayList$Itr.next(ArrayList.java:854)
}

1 个答案:

答案 0 :(得分:0)

这种情况只能在多线程情况下发生。

我相信线程1必须在执行第855行之前立即停止。线程2会出现并将ArrayList.this.elementData设置为一个新的(较小的)数组。

提供比ArrayIndexOutOfBoundsException异常更好的异常是一种廉价的检查,否则会抛出异常。从理论上讲,优化器甚至可以检测到显式检查数组边界,并省略了对ArrayIndexOutOfBoundsException的检查。