2

I have the following situation:

In a main function if some controller class I retrieve 10 product objects from my DB. These are hold in an ArrayList object.

Afterwards I create three classes which extend Runnable and I give to each class the product-ArrayList into the constructor.

In each of the constructors is a new local ArrayList created and the objects in the product-ArrayList are added:

this.products = new ArrayList();
products.addAll(productListParam);

Afterwards I start each of three threads and they iterate over their local products-lists and also modify it.

I'm getting a ConcurrentModificationException while iterating over the local product ArrayList..

Why is this happening? I was assuming that if I create a complete new list in each thread I can modify this locally as much as I want without caring about the other threads - am I right? Or does the removal of some object from a local list affect the pbjects somehow so that the other threads throw the Concurrent Modification Exception?

Actually the stacktrace looks like:

java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
at java.util.ArrayList$Itr.next(ArrayList.java:791)
at com.x.y.class.method(Classname.java:326)

and Classname.java at 326 looks like:

325:List<Product> productsToDelete = new ArrayList();
326:for(Product p: products){
        ...
        if(xy){
              productsToDelete.add(p);
        }
    }
    products.removeAll(productsToRemove);

Maybe someone has a hint for me what I'm doing wrong?

Edit: Inside the loop the product object p is just used for reading. Additionally there are no modifications done to the products-ArrayList. They are only added to a second "toBeRemoved" list to remove them later after the for-loop finished.. I edited the code above.

I think I'm mostly interested in the question if I can create several list-objects, add the same product-objects to each of them via the addAll()-method and then can to anything with it in each thread without caring about the other threads?!

mr.simonski
  • 352
  • 3
  • 15

2 Answers2

3

You can't modify the Collection inside an enhanced for loop that iterates over its elements. Not even if you only have a single thread.

You didn't include the code inside the enhanced for loop, but if what you need to do inside it is remove elements from the list, you can use an explicit iterator.

Iterator<Product> iter = products.iterator();
While (iter.hasNext() {
    Product p = iter.next();
    ....
    if (some condition)
        iter.remove();
    ....
}
Eran
  • 387,369
  • 54
  • 702
  • 768
  • Sorry, I didn't include the code from the for-loop, but there is no modification done at all. The product-objects iterated over are just used in read-mode to get some information. There is nothing taken from the list or added. Also nothing changed inside the product objects. Additionally the stacktrace points to the for(Product p: products) statement which I never saw before.. – mr.simonski Oct 04 '14 at 14:57
  • @dacrow Your question implies you are modifying the lists - `Or does the removal of some object from a local list affect the...`. Where are you modifying them? – Eran Oct 04 '14 at 14:58
  • Sorry Eran for my unprecise description, I've edited my question. – mr.simonski Oct 04 '14 at 15:05
0

Sorry guys to bother you, I did a bad beginner fault!

I was setting the mentioned product-ArrayList manually later from some other code basis and did overwrite the new ArrayList.. so all threads again used only one ArrayList and the ConcurrentModificationException occured.

As you see within this example, always double check your code :)

Sorry for bothering you..

mr.simonski
  • 352
  • 3
  • 15