【问题标题】:Why ConcurrentModificationException in Vector?为什么在 Vector 中出现 ConcurrentModificationException?
【发布时间】:2017-03-03 03:03:36
【问题描述】:

这是我的测试:

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?

【问题讨论】:

  • 它抛出异常,因为它在 调用next() 之间被修改。您必须在整个迭代中进行同步以使其成为线程安全的。令人惊讶的是,我没有看到 Vector 类中明确记录了这一点,就像 Collections.synchronizedList() 一样。
  • @shmosel 如果您将其发布为答案,我将投票赞成。
  • 您可以在这里查看更多信息journaldev.com/378/java-util-concurrentmodificationexception,这让您更清楚地知道如何解决这个问题
  • @DavidWallace 这不是很令人满意。我想把它作为一个问题发布。

标签: java multithreading vector


【解决方案1】:

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

【讨论】:

  • 我何时创建Iterator iterator=list.iterator();
  • 当你做iterator.next()时,值没有更新,线程不安全,导致问题
  • 好的,对吗:当线程一创建Iterator iterator=list.iterator();the expectedCount = modCount.但是线程二改变了modCount。所以当线程一执行迭代器.next().问题就出现了????
猜你喜欢
  • 2014-09-11
  • 2011-08-29
  • 1970-01-01
  • 2014-09-26
  • 2018-01-05
  • 1970-01-01
  • 1970-01-01
  • 2014-05-14
  • 2011-08-18
相关资源
最近更新 更多