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

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

问题描述

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

我上面提到的异常和源$ C ​​$ C是获得如下:

 公共无效loadItems(ArrayList的列表){
    如果(名单= NULL&放大器;!&安培;则为list.size()0){
        super.clear();
        迭代器迭代器= list.iterator();
        而(iterator.hasNext()){
            // VendorItem项目=(VendorItem)iterator.next();
            //负载(新的整数(item.getVendorItemId()),项目);            obj对象= iterator.next(); //<<这就是它说的异常来
            如果(OBJ的instanceof InvoiceItem){
                InvoiceItem项目=(InvoiceItem)目标文件;
                负载(新的整数(item.getInvoiceItemId()),项目);
                //logger.debug(\"**装载发票项目+ item.toString());
            }
            否则,如果(OBJ的instanceof PurchaseOrderItem){
                PurchaseOrderItem项目=(PurchaseOrderItem)目标文件;
                负载(新的整数(item.getPoItemId()),项目);
                //logger.debug(\"**装载订单项目+ item.toString());
            }
            否则,如果(OBJ的instanceof ShipmentItem){
                ShipmentItem项目=(ShipmentItem)目标文件;
                负载(新的整数(item.getShipmentItemId()),项目);
                logger.debug(**装载ShipmentItem物品+ item.toString());
            }
            //
            否则,如果(OBJ的instanceof VendorItem){
                VendorItem项目=(VendorItem)目标文件;
                负载(新的整数(item.getVendorItemId()),项目);
                logger.debug(**装载VendorItem+ item.toString());
            }
            //
            其他{
                logger.debug(***没有发票/ PO /货项目);
            }
        }
    }}

我已经看到了相关的问题,但他们不符合我的情况,所以我希望,如果有人能说出真正的原因为什么发生这种情况。


解决方案

ArrayList是不同步的。这意味着,在TimerThread别的正在修改的ArrayList。

下面的文档说什么:


  

请注意,此实现不是同步的。如果多个线程
  同时访问一个ArrayList实例,并且该至少一个
  线程修改了该列表结构,它必须被同步
  外部。 (结构上修改是指添加任何操作或
  删除一个或多个元件,或明确地调整大小背衬阵列;
  仅设置一个元素的值不是结构
  修改)。这一般是通过在一些同步操作来完成
  对象自然封装列表。如果不存在这样的对象,
  名单应该是包装使用Collections.synchronizedList
  方法。这最好在创建时进行,以prevent意外
  不同步访问列表:


 清单列表= Collections.synchronizedList(新的ArrayList(...));

包装使用Collections.synchronizedList()应该解决问题列表中。

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 is not synchronized. This means that in your TimerThread something else is modifying the ArrayList.

Here's what the docs say:

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(...));

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

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

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