-2

I am trying to make a simulation of a program which simulates different threads removing and adding objects in an ArrayList. However, late in the simulation I get concurrentModificationExceptions (when the threads are trying to access and modify the same variable while an iterator is being used to iterate through the data). I have searched it up and seen some topics about this saying that I needed to use locks/synchronization and/or using ListIterators instead of enhanced for-loops, however, none of these options seemed to fix the problem. Here is what I have tried to do so far:

public Object removeSomething1(){
    synchronized(this){ //Also tried only putting it around the remove block
        for(Object o : myList){
            myList.remove(o);
            return o;
        }
    }

}

//This is another variaton which did not yield any improved result

public Object removeSomething2(){
    ListIterator<Object> iter = myList.listIterator();
        While(iter.hasNext()){
            Object s = iter.next();
            synchronized(this){
                iter.remove();

            }
            return s;

        }

    }

//After some request here is also the simple code which adds to the list

public addSomething(Object o){
    myList.add(o);
}

I execute 5 threads which calls upon these methods in their run() method in an interval of 500ms (using Thread.sleep()). If I increase the sleep timer in each thread and put a Thread.sleep() between each instanciation of threads, the problem seems to go away, but I want the threads to run at (closely) the same time without them interfering with the iterator at the same time which envokes the ConcurrentModificationException.

tomSurge
  • 256
  • 1
  • 5
  • 15
  • Instead of `for (Object o : myList) myList.remove(o);` why not just have `myList.removeAll()` ? – khelwood Jan 30 '16 at 22:40
  • Because I do not want to remove all objects. I want each thread to remove its own object. This is just a sample code of a greater and more substantial program where each thread adds and thereafter removes the object it added, but as stated, the Exception is only thrown in the "remove-section" of the code. – tomSurge Jan 30 '16 at 22:44
  • @tomSurge can you show all code that is modifying the list? What is adding to the list and how? By the way, what you have posted does not even compile. – Jaroslaw Pawlak Jan 30 '16 at 22:48
  • Please don't post code that I can see won't compile and tell me it compiles. If you copy what you have there into a source file, there is no way it will compile, because not every path through the method leads to a `return` statement. – khelwood Jan 30 '16 at 23:02
  • It will be something like "cannot resolve symbol o" for the first method and "missing return statement" for the second method. What about the code that adds to the list? – Jaroslaw Pawlak Jan 30 '16 at 23:02
  • @JaroslawPawlak I added the method now. – tomSurge Jan 30 '16 at 23:07
  • 1. Your both "loops" that "remove elements" can be simplified to `list.remove(0)`. I have no idea what you are actually trying to achieve there, because none of them compiles. 2. All modifications of the list have to be synchronised, your `add` is not. – Jaroslaw Pawlak Jan 30 '16 at 23:09
  • 1
    Generally speaking, you'll need to move the `synchronized` block to contain all of `removeSomething2()`. You _must_ synchronize the entire iteration. – Louis Wasserman Jan 31 '16 at 04:54
  • That simple answer seemed to fix my problem! Thank-you! @LouisWasserman – tomSurge Jan 31 '16 at 12:36

1 Answers1

-2

After a suggestion from the user Louis Wasserman, I move the synchronized block to contain all of removeSomething2(). This makes sense as it now only let's one thread do the whole iteration at a time. This is how the solution looks:

public Object removeSomething2(){
synchronized(this){
    ListIterator<Object> iter = myList.listIterator();
        While(iter.hasNext()){
            Object s = iter.next();
            iter.remove();
            return s;
        }
    }
}
tomSurge
  • 256
  • 1
  • 5
  • 15
  • 1
    This all code is equivalent to `myList.remove(0);`... And instead of having entire method body in synchronized block on `this`, you could just make the method synchronized... And finally, it is not a solution to the problem you have described, if you are adding and removing items to/from the list on multiple threads, while you adds are still not synchronized... – Jaroslaw Pawlak Jan 31 '16 at 17:43
  • Also, still definitely won't compile. – khelwood Feb 01 '16 at 09:35