Как одновременно изменить вектор
Я должен убедиться при итерации вектора; на этом векторе обновлений нет 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 или более ранней версии.
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 - если следующий метод еще не был вызван, или метод удаления уже был вызван после последнего вызова следующего метода.
И последнее по порядку, но не по значению: состояние гонки, уже упомянутое Сотириосом (+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()
, Если вы звоните next()
при добавлении элементов непосредственно в Vector
, вы получите ConcurrentModificationException
,