我必须确保在迭代 Vector 时;该 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) OutOfMemoryError
或 2) IllegalStateException
.您能否解释一下导致这两个异常的原因。以及如何实现避免ConcurrentModificationException
Vector
的目标?
我必须为 Java 1.4.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
}
这是一个无限循环,每次迭代都会增加内存使用量。因此,您迟早会遇到内存不足的情况。
我建议使用一个好的旧 for 循环来插入值。如果您确实想要迭代某些内容,请使用迭代器:)
更多:您正在与非最终成员同步。
更多: 迭代器.删除抛出...
IllegalStateException - 如果尚未调用下一个方法,或者在上次调用下一个方法后已经调用了 remove 方法。
最后但并非最不重要的一点是:索蒂里奥斯已经提到的比赛条件(+1 为他)。无论何时同步,请确保同步关键资源上的每个调用。
你手上有一个很好的旧比赛条件。
你的第一个Thread
,除了在你的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;
}
光标从 0
开始,elementCount
是Vector
的大小。此调用将永远不会返回false
。您的while
循环循环,添加元素,直到程序内存不足。cursor
永远不会前进,因为你从不打电话给next()
。如果您在将元素直接添加到Vector
时确实调用next()
,您将获得ConcurrentModificationException
。