Как одновременно изменить вектор

Я должен убедиться при итерации вектора; на этом векторе обновлений нет 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,

Другие вопросы по тегам