ConcurrentModificationException without changing an object

I have the following piece of code that throws a ConcurrentModificationException. I don’t modify the object at all products,

List<Product> products = Product.findActiveByFilter(filters);
Set<Long> temp = new HashSet<Long>();
List<Product> resultSetTemp = new ArrayList<Product>();
for (Product product : products) { // << Exception points to this
    if(!temp.contains(product.getId())){
        temp.add(product.getId());
        resultSetTemp.add(product);
    }
}
products.clear();
products.addAll(resultSetTemp);

I have seen this exception pop up several times, but I cannot reproduce it (this happens randomly).

Product.findActiveByFilteris a method that returns a new instance List<Product>that was created from cached List<Product>.

Edit: I found a way to reproduce the error. The code is called when the customer wants the products (his web store), and the website loads more items when the customer scrolls down. This throws an exception (since the server has not yet completed a response with the products and received another call). Racial conditions, fun!

+4
2

, products ( ). Product.findActiveByFilter, new ArrayList<Product>(products); , ( , ).

public static List<Product> findActiveByFilter(ArrayList<FilterPair> filters) {
    List<Product> products = getCachedAllProductsByFirstSupplier();

    if (products == null) {
        products = new ArrayList<Product>();
    }

    if(filters.size() > 0) {
        List<Product> productsFiltered = new ArrayList<Product>(products);
        // ... MANY checks here for the filters ...

        return productsFiltered;
    }

    return new ArrayList<Product>(products); // Do not give cached copy, was 'return products;'
}

findActiveByFilter 2 , -. , - ( , - ).

+1

?

List<Product> products = Product.findActiveByFilter(filters);
Set<Long> temp = new HashSet<Long>();
List<Product> resultSetTemp = new ArrayList<Product>();

Iterator ite = products.iterator();

while (ite.hasNext()) {

    Product product = ite.next();

    if(!temp.contains(product.getId())){

        temp.add(product.getId());
        resultSetTemp.add(product);
    }
}
products.clear();
products.addAll(resultSetTemp);

: . , , .

0

Source: https://habr.com/ru/post/1532634/


All Articles