简体   繁体   中英

ConcurrentModificationException with synchronized list

I get an ConcurrentModificationException error in following situation. The line where this occurs is marked with "<-------- ConcurrentModificationException"

  • I have a main thread which reads from a list as follow:

     List<ThemeCacheIndex> list = Collections.synchronizedList(themeCacheList); synchronized (list) { Iterator<ThemeCacheIndex> it = list.iterator(); while (it.hasNext()) { ThemeCacheIndex themeCacheIndex = it.next(); <-------- ConcurrentModificationException doSomething(); } } 
  • I have a AsyncTask which deletes from this list:

      @Override protected String doInBackground(String... params) { someElementsToRemove = calculateWhichElementsToRemove(); for(int i=0 ; i < someElementsToRemove.size() ; i++){ themeCacheList.remove(someElementsToRemove.get(i)); } } 

I can imagine, that it comes to a concurrent situation, but I thought to prevent this with a synchronized list on the main thread.

It seems I did not understood the concept of multithreading and shared objects.

Can someone help me out of this problem ? How can I prevent this conflict ?

Quoting Collections Javadoc :

Returns a synchronized (thread-safe) list backed by the specified list. In order to guarantee serial access, it is critical that all access to the backing list is accomplished through the returned list.

If your AsyncTask modifies the themeCacheList , the synchronization as you did it won't help, as a backing list is modified.

The AsyncTask code is fine. Do this for the "main" thread code:

synchronized (themeCacheList) {
    Iterator<ThemeCacheIndex> it = themeCacheList.iterator();
    while (it.hasNext()) {
        ThemeCacheIndex themeCacheIndex = it.next();
        doSomething();
    }
}

As you can see I've removed Collections.synchronizedList because it is redundant and I'm synchronizing directly on themeCacheList .

Not sure I have a good solution, but I guess these 2 examples shows the problem and a possible solution. The "Possible duplicate" Answers do not show any solution, but just explaining what is the problem.

@Test
public void testFails(){

    List<String> arr = new ArrayList<String>();
    arr.add("I");
    arr.add("hate");
    arr.add("the");
    arr.add("ConcurrentModificationException !");

    Iterator i = arr.iterator();


    arr.remove(2);

    while(i.hasNext()){
        System.out.println(i.next());
    }
}

@Test
public void testWorks(){

    List<String> arr = new CopyOnWriteArrayList<>();
    arr.add("I");
    arr.add("hate");
    arr.add("the");
    arr.add("ConcurrentModificationException !");

    Iterator i = arr.iterator();


    arr.remove(2);

    while(i.hasNext()){
        System.out.println(i.next());
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM