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)我得到了上面提到的异常,源代码如下:
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");
}
}
}
}我已经看到了相关的问题,但它们不符合我的方案,所以我希望如果有人能指出发生这种情况的真正原因。
发布于 2013-11-26 02:00:28
ArrayList未同步。这意味着在您的TimerThread中,有其他东西正在修改ArrayList。
以下是文档所说的:
请注意,此实现不是同步的。如果多个线程并发访问一个ArrayList实例,并且至少有一个线程在结构上修改了列表,则必须在外部同步该实例。(结构修改是添加或删除一个或多个元素,或显式调整支持数组大小的任何操作;仅设置元素的值不是结构修改。)这通常是通过在自然封装列表的某个对象上进行同步来实现的。如果不存在这样的对象,则应该使用Collections.synchronizedList方法“包装”列表。最好在创建时执行此操作,以防止意外不同步地访问列表:
List list = Collections.synchronizedList(new ArrayList(...));使用Collections.synchronizedList()包装这个列表应该可以解决这个问题。
发布于 2013-11-26 02:02:27
如果load在您使用Iterator时对ArrayList进行了更改,那么是的,您将得到一个ConcurrentModificationException,因为它使迭代器处于未知状态。
列表有第二个迭代器(可以用.listIterator()获取的ListIterator),可用于在迭代时进行更改。请注意,这只适用于通过迭代器所做的更改...在迭代器之外所做的更改仍然会有这个问题。
CopyOnWriteArrayList保证不会从它的迭代器中抛出ConcurrentModificationException,因为它是线程安全的,并且更改会生成新的副本……但是迭代器也不会意识到您所做的任何更改。
https://stackoverflow.com/questions/20199760
复制相似问题