Error in android java.util.ConcurrentModificationException

3

I'm doing an app for Android , and part of my code is like the following:

public void loop(){

   for(Car car:carList)
        car.run();

}

The bad thing is that I get the error java.util.ConcurrentModificationException . I was researching, I used iterators and the java notation synchronized , because as I read in the Oracle documentation, the error can be generated by several threads using my "loop" method.

public synchronized void loop(){
 Iterator<Car> carIterator = carList.iterator();
 while(cardIterator.hasNext()){
  carIterator.next().run();
 }
}

I really do not know what else can solve this problem. I use the class of this method and this one, above all, in background services and activities , I also use them (using the singleton pattern to instantiate).

Thanks guys for the support! Well, to give more details of my problem, the carList is an ArrayList with Car objects My class car is this:

public class Car{
   private int mSpeed;
   private int mDistance; //inicializo con cero
    ........
   public void run(){
       mSpeed=getRandomSpeed();
       mDistance+=mSpeed;
       updateDistanceInDB();//Aquí lo guardo en una base de dato sqlite
   }
   .........   

}

-The error tells me that this was generated on the line where I execute the run () method inside the loop. Also, what is strange is that this error does not happen in another cell phone that I have. -This is the page of the official documentation of oracle that tells me that the error may be due to several threads using my list, so use synchronized but it did not solve

link

Why on other phones will work and others will not? Thanks guys for your help!

    
asked by Carlos Chávez 27.10.2016 в 04:39
source

2 answers

4
  

because as I read in the Oracle documentation, the error can be generated by several threads using my "loop" method.

It is not correct. What the exception says is that:

  • You have created an iterator (well, the for syntax does it for you)

  • Between calls and calls to next() of the iterator, the content of the original% Collection has been modified (basically, someone has called add() , remove() or reset() ). Actually, it does not matter if it is from another thread or from it (are you sure that the run() method does not modify the list?). When you make the next call to next() , the exception jumps.

  • Possible solutions:

    1) Identify what other code is modifying the collection, and put your loop and the other code in a critical section ( synchronized ), using the same object of lock .

    Note that if you are modifying the list from the same thread (for example from the run() method), synchronization does not help (synchronization prevents two threads from executing interfering blocks of code) each other at the same time, if it is the fault of run() you will be inside the same thread ).

    2) If you do not want / can with 1), make a new Collection with the contents of the original and iterate over it; List<Car> listCopy = new ArrayList<>(carList); .

    The main problem with this approach is that you do not know what the original cause of the problem is, so you do not know if you should update the list because the original list has changed.

        
    answered by 27.10.2016 в 09:34
    0

    To fix the error:

      

    java.util.ConcurrentModificationException

    What you are saying "The error can be generated by several threads using my" loop "method." It's partly true but what actually happens is that your list is being modified and at the same time is probably being used in another thread

    You can solve this problem by simply creating a copy of your List in this case carList :

    List<Car> copiaList = new ArrayList<Car>(carList);  
    

    In this copy you can perform the operations without problem and avoid the error ConcurrentModificationException .

        
    answered by 27.10.2016 в 14:23