Search code examples
javavectorjava.util.concurrentconcurrency

How to concurrently modify a Vector


I have to ensure while iterating the Vector; there is no update on that Vector to avoid ConcurrentModificationException. I can use concurrent collection. But i just want to give a try on Vector. Below is the code I have written.

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();
    }
}

But the above code is throwing 1) OutOfMemoryError OR 2) IllegalStateException. Could you please explain what is causing these two exception. And how to achieve my goal of avoiding ConcurrentModificationException on a Vector?

I have to solve this for Java 1.4.2 or prior.


Solution

  • One part of your Problem:

     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
     }
    

    This is an infinite loop that increases memory usage in each iteration. So you'll run into an OutOfMemory sooner or later.

    I suggest using a good old for-loop for inserting values. Use an iterator if you actually want to iterate something :)

    More: You are synchronizing against a non-final member.

    More: Iterator.remove throws ...

    IllegalStateException - if the next method has not yet been called, or the remove method has already been called after the last call to the next method.

    And last but not least: The race condition already mentioned by Sotirios (+1 for him). Whenever you synchronize, make sure you synchronize every call on the critical resource.