0

我必须确保在迭代向量时;没有要避免的 Vector 更新ConcurrentModificationException。我可以使用并发收集。但我只是想尝试一下 Vector。下面是我写的代码。

public class TestConcurrentModification1 {
    Vector a = new Vector();

    public static void main(String[] args)  {
        final TestConcurrentModification1 obj = new TestConcurrentModification1();

        new Thread(){
            public  void run(){
                for(int i = 0; i < 5; i++){
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {}
                    obj.a.add(""+i);                
                }
                System.out.println(obj.a);
            }
        }.start();

        new Thread(){
            public  void run(){
                try {
                    Thread.sleep(10);
                    } catch (InterruptedException e) {
                    }
                synchronized (obj.a) {
                    Iterator itr = obj.a.iterator();
                    while(itr.hasNext()) {
                        obj.a.add("TEST");//java.lang.OutOfMemoryError: Java heap space
                        //itr.remove(); //java.lang.IllegalStateException
                    }
                }
            }
        }.start();
    }
}

但是上面的代码抛出 1) OutOfMemoryErrorOR 2) IllegalStateException。您能否解释一下导致这两个异常的原因。以及如何实现我避免ConcurrentModificationException在 a 上的目标Vector

我必须为 Java 1.4.2 或更早版本解决这个问题。

4

2 回答 2

2

您的问题的一部分:

 Iterator itr = obj.a.iterator();
 while(itr.hasNext()) {
     obj.a.add("TEST");// <- if itr.hasNext() would have returned false in next iteration, now it won't
 }

这是一个无限循环,会在每次迭代中增加内存使用量。因此,您迟早会遇到 OutOfMemory。

我建议使用一个很好的旧 for 循环来插入值。如果您真的想迭代某些东西,请使用迭代器:)

更多:您正在与非最终成员同步。

更多: Iterator.remove 抛出 ...

IllegalStateException - 如果尚未调用下一个方法,或者在最后一次调用下一个方法之后已经调用了 remove 方法。

最后但并非最不重要的一点:Sotirios 已经提到的比赛条件(他+1)。无论何时进行同步,请确保同步关键资源上的每个调用。

于 2013-10-15T15:12:30.433 回答
2

你手上有一个很好的旧比赛条件。

您的 first Thread,除了将第一个元素添加到 your 之外Vector,绝对没有任何用途。您可以将其替换为

obj.a.add("first");

正如其他人所指出的,牛肉就在这里

Iterator itr = obj.a.iterator();
while (itr.hasNext()) {
    obj.a.add("TEST");// java.lang.OutOfMemoryError: Java
    // heap space
    // itr.remove(); //java.lang.IllegalStateException
}

itr.hasNext()被实现为

public boolean hasNext() {           
    return cursor != elementCount;
}

光标从哪里开始,0elementCount你的Vector. 此调用将永远不会返回false您的while循环带有循环,添加元素,直到程序内存不足。cursor永远不会前进,因为你从不打电话next()。如果您next()在直接向 中添加元素时调用Vector,您将得到一个ConcurrentModificationException.

于 2013-10-15T15:20:04.887 回答