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?
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. 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.
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.
Try using java.util.concurrent.CopyOnWriteArrayList
instead of ArrayList
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.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With