为什么Vector中的ConcurrentModificationException?

时间:2017-03-03 03:03:37

标签: java multithreading vector

这是我的测试:

public static List<String> list =new Vector<String>();
@Test
public void main(){
    new ThreadOne().start();
    new ThreadTwo().start();
}
public static void printAll(){
    String valueString= null;
    Iterator<String> iterator=list.iterator();
    while(iterator.hasNext()){
        valueString = (String) iterator.next();
        System.out.print(valueString+",");
    }
    System.out.println("\n");
}
public static class ThreadOne extends Thread{
    public void run(){
        int i=10;
        while(i<100000){
            list.add(String.valueOf(i));
            printAll();
            i++;
        }
    }

}
public static class ThreadTwo extends Thread{
    public void run(){
        int i=0;
        while(i<100000){
            list.add(String.valueOf(i));
            printAll();
            i++;

        }
    }

}

我在Vector.class中看到了关于迭代器的源代码:

 public synchronized Iterator<E> iterator() {
    return new Itr();
}

/**
 * An optimized version of AbstractList.Itr
 */
private class Itr implements Iterator<E> {
    int cursor;       // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;

    public boolean hasNext() {
        // Racy but within spec, since modifications are checked
        // within or after synchronization in next/previous
        return cursor != elementCount;
    }

    public E next() {
        synchronized (Vector.this) {
            checkForComodification();
            int i = cursor;
            if (i >= elementCount)
                throw new NoSuchElementException();
            cursor = i + 1;
            return elementData(lastRet = i);
        }
    }

我很了解它。当程序执行iterator.next()时, 向量对象被锁定,当程序执行list.add()时,向量也被锁定。变量“expectedModCount”总是等于“modCount”。为什么会出现ConcurrentModificationException?

1 个答案:

答案 0 :(得分:0)

迭代器的下一个方法是同步的。这意味着它在读取每个元素后释放锁定,然后在读取后续元素时获取锁定。在调用next之前,向量内容之间仍有机会以触发ConcurrentModificationException的方式进行更改。