我得到了以下导致ConcurrentModificationException的代码。我根本没有修改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);
我已多次看到此异常弹出窗口,但我无法重现它(它随机发生)。
Product.findActiveByFilter
是一种方法,它返回已从缓存的List<Product>
构建的List<Product>
的新实例。
编辑:我找到了重现错误的方法。当客户想要产品(它是网上商店)时,代码被调用,当客户端向下滚动时,网站会加载更多项目。这会触发异常(因为服务器尚未完成对产品的响应,并获得另一个调用)。比赛条件,好玩!
答案 0 :(得分:1)
正如一些人已经说过的那样,它是由一个单独的'修改'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,由网站调用。第一个包括一个过滤器,但第二个没有(所以第一个仍然很忙,而第二个直接返回)。
答案 1 :(得分:0)
您是否尝试过使用迭代器?
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);
编辑:刚看到您的更新。鉴于此,这可能无法解决您的问题。