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) OutOfMemoryError или 2) IllegalStateException. Не могли бы вы объяснить, что вызывает эти два исключения. И как достичь моей цели - избежать ConcurrentModificationException на Vector?

Я должен решить это для Java 1.4.2 или ранее.

+0

Не используйте 'Вектор'. Вместо этого выберите подходящий класс из пакета 'java.util.concurrent'. –

+1

'ConcurrentModificationException' не обязательно для одновременного, как в multi -Thread. Вы не можете добавлять/удалять из коллекции, итерации по ней. Вы можете удалить, если используете сам «Итератор». –

+0

Кроме того, обратите внимание на это Q/A: [Почему класс Java Vector считается устаревшим или устаревшим?] (Http://stackoverflow.com/q/1386275/1065197) –

ответ

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.

Я предлагаю использовать старый добрый цикл для вставки значений. Используйте итератор, если вы действительно хотите, чтобы итерации что-то :)

Подробнее: Вы синхронизированы с нефиксированным членом.

Подробнее: Iterator.remove бросает ...

IllegalStateException - если следующий метод еще не был назван, или метод удалить уже был вызван после последнего вызова к следующему способу.

И последнее, но не менее важное: состояние гонки, о котором уже упоминал Сотириос (+1 для него). Всякий раз, когда вы выполняете синхронизацию, убедитесь, что вы синхронизируете каждый вызов на критическом ресурсе.

+0

Нет, если я прокомментирую эту строку «obj.a.add (« TEST ») «моя программа никогда не заканчивается ... Проблема в другом месте ... –

+0

Конечно, это не так, потому что ваш итератор никогда не продвигается!« HasNext »не меняет позицию итератора. Вы должны называть' next' внутри цикла – Fildor

+0

@KanagaveluSugumar Обратите внимание, что если вы вызываете 'next()', вы получите 'ConcurrentModificationException'. –

2

У вас на руках хорошие старые условия гонки.

Ваш первый 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.

Смежные вопросы