ArrayList 处理中的 java.util.ConcurrentModificationException [英] java.util.ConcurrentModificationException in ArrayList processing

查看:34
本文介绍了ArrayList 处理中的 java.util.ConcurrentModificationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at com.alpha.beta.purchasing.item.VendorItemList.loadItems(VendorItemList.java:51)
at com.alpha.beta.purchasing.Shipment.loadItems(Shipment.java:1006)
at com.alpha.beta.purchasing.Shipment.loadItems(Shipment.java:953)
at com.alpha.beta.purchasing.Shipment.getItemTotal(Shipment.java:1503)
at com.alpha.beta.purchasing.Shipment.getShipmentTotal(Shipment.java:854)
at com.alpha.beta.quickreports.PurchasingGenericListSourceMapper.fillPurchaseReceivingItemListForQuickReportsTask(PurchasingGenericListSourceMapper.java:144)
at com.alpha.beta.quickreports.PurchasingGenericListSourceMapper$2.run(PurchasingGenericListSourceMapper.java:105)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)

我得到上面提到的异常,源代码如下:

I am getting above mentioned Exception and source code is below:

public void loadItems(ArrayList list) {
    if(list != null && list.size() > 0) {
        super.clear();
        Iterator iterator = list.iterator();
        while(iterator.hasNext()) {
            // VendorItem item = (VendorItem)iterator.next();
            //load(new Integer(item.getVendorItemId()), item);

            Object obj = iterator.next(); // << This is where it says exception comes
            if(obj instanceof InvoiceItem) {
                InvoiceItem item = (InvoiceItem)obj;
                load(new Integer(item.getInvoiceItemId()), item);
                //logger.debug("** loading invoice Item " + item.toString());
            }
            else if(obj instanceof PurchaseOrderItem) {
                PurchaseOrderItem item = (PurchaseOrderItem)obj;
                load(new Integer(item.getPoItemId()), item);
                //logger.debug("** loading PO Item " + item.toString());
            }
            else if(obj instanceof ShipmentItem) {
                ShipmentItem item = (ShipmentItem)obj;
                load(new Integer(item.getShipmentItemId()), item);
                logger.debug("** loading ShipmentItem Item " + item.toString());
            }
            //
            else if(obj instanceof VendorItem) {
                VendorItem item = (VendorItem)obj;
                load(new Integer(item.getVendorItemId()), item);
                logger.debug("** loading VendorItem " + item.toString());
            }
            //
            else {
                logger.debug("*** neither invoice/PO/shipment item");
            }
        }
    }

}

我已经看到了相关的问题,但它们不符合我的情况,所以我希望有人能指出发生这种情况的真正原因.

I have seen the related questions but they doesn't meet my scenario so i was hoping that if someone can point out the real cause why this is happening.

推荐答案

ArrayList 未同步.这意味着在您的 TimerThread 中,其他东西正在修改 ArrayList.

ArrayList is not synchronized. This means that in your TimerThread something else is modifying the ArrayList.

以下是文档的说明:

请注意,此实现不是同步的.如果多个线程同时访问一个 ArrayList 实例,并且至少有一个线程在结构上修改列表,它必须是同步的外部.(结构修改是任何增加或删除一个或多个元素,或显式调整后备数组的大小;仅仅设置元素的值不是结构性的修改.)这通常是通过同步一些自然封装列表的对象.如果不存在这样的对象,该列表应该使用 Collections.synchronizedList 进行包装"方法.这最好在创建时完成,以防止意外对列表的非同步访问:

Note that this implementation is not synchronized. If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more elements, or explicitly resizes the backing array; merely setting the value of an element is not a structural modification.) This is typically accomplished by synchronizing on some object that naturally encapsulates the list. If no such object exists, the list should be "wrapped" using the Collections.synchronizedList method. This is best done at creation time, to prevent accidental unsynchronized access to the list:

   List list = Collections.synchronizedList(new ArrayList(...));

使用 Collections.synchronizedList() 包装这个列表应该可以解决这个问题.

Wrapping this list using Collections.synchronizedList() should fix the problem.

这篇关于ArrayList 处理中的 java.util.ConcurrentModificationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆