Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle ConcurrentModificationException in Android

Im trying to delete item from a ArrayList. Some times it pops an exception, java.util.ConcurrentModificationException.

First I tried to remove them by array_list_name.remove(i), but it failed and some people were asked to use Iterator instead. So my current code is as follows:

for (Iterator<Collectable> iter = array_list_name.iterator(); iter.hasNext();) {
   Collectable s = iter.next();
   if (s.equals(array_list_name.get(id))){
       iter.remove();
       return true;
   }
}

And I call array_list_name inside onDraw() function in view. My view is a SurfaceView. Can anyone suggest me how to delete items from ArrayList without getting this error?

like image 895
dinesh707 Avatar asked Jul 08 '11 08:07

dinesh707


People also ask

How do you overcome ConcurrentModificationException?

To Avoid ConcurrentModificationException in single-threaded environment. You can use the iterator remove() function to remove the object from underlying collection object. But in this case, you can remove the same object and not any other object from the list. Let's run an example using Concurrent Collection classes.

What causes ConcurrentModificationException?

What Causes ConcurrentModificationException. The ConcurrentModificationException generally occurs when working with Java Collections. The Collection classes in Java are very fail-fast and if they are attempted to be modified while a thread is iterating over it, a ConcurrentModificationException is thrown.

Who throws ConcurrentModificationException?

Class ConcurrentModificationException. This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible. For example, it is not generally permissible for one thread to modify a Collection while another thread is iterating over it.


3 Answers

Try using java.util.concurrent.CopyOnWriteArrayList instead of ArrayList

like image 96
Murat Can ALPAY Avatar answered Oct 08 '22 10:10

Murat Can ALPAY


Have you ever thought to use Vector List ? If you need a thread-safe implementation, you should use Vector instead of ArrayList. Vector list's usage is same with ArrayList. Just change its type with Vector.

Unsafe usage

ArrayList<FutureTask> futureTasks;

Change with

Vector<FutureTask> futureTasks;

That's all.

like image 21
oguzhan Avatar answered Oct 08 '22 08:10

oguzhan


Seems from the comments that your ArrayList<Collectable> is accessed from the onDraw() method in one thread, by the UI, concurrently with you removing items from it in another thread.

So, why not just wrap both accessors in a

synchronized(array_list_name)
{
    // UI access code or item removal code
}

Note that this might make your UI laggy if removing items takes a long time. If this is the case, consider making a list of all item indexes to be removed, and remove them in a tight synchronized loop after iterating over the whole list.

Update

It seems to me your whole code snippet could be simplified to just:

synchronized(array_list_name)
    return array_list_name.remove(id);
like image 40
Bjarke Freund-Hansen Avatar answered Oct 08 '22 08:10

Bjarke Freund-Hansen