使用多執行緒出現: java.util.ConcurrentModificationException的問題。
在一個批量Insert業務中,使用多執行緒進行約束insert。其中出現的一個問題。
部分資料是成功insert的。 百度得知此問題發生的原因是:在迴圈迭代中,如果對Vetor、ArrayList進行修改,就可能對丟擲這個異常。仔細錯誤檢查程式碼:entryList的作用域過大,並且,在後面做了entryList.clear的操作。物件還是那個物件,只是把裡面的元素清空了而已。
仔細錯誤檢查程式碼
List<InStorageMissionEntry> entryList = new ArrayList<InStorageMissionEntry>();
修改後的正確程式碼應該是:
List<InStorageMissionEntry> entryList =null; for (String billno : fbillnos) { InStorageMission mission = setMission(user); entryList = new ArrayList<InStorageMissionEntry>(); for (PurReceiveOrder purReceiveOrder : purReceiveOrderList) { String fbillno = purReceiveOrder.getFbillno(); if(billno.equals(fbillno)) { mission.setRecOrgId(purReceiveOrder.getRecOrgId()); mission.setRecOrgNumber(purReceiveOrder.getRecOrgNumber()); InStorageMissionEntry setEntry = setEntry(user,purReceiveOrder); entryList.add(setEntry); Integer Fid = purReceiveOrder.getfId(); Map<String,Integer> map = new HashMap<String, Integer>(); map.put("billId", Fid); map.put("entryId", purReceiveOrder.getEntryId()); map.put("missionStatus", 3); mapList.add(map); } } System.out.println("entryList====="+entryList.size()); if(mission!=null && entryList !=null && entryList.size()>0) { try { synchronized (this) { inStorageMissionService.insertInStorageMission(mission, entryList); msg = new Msg(); msg.setCode(100); msg.setMsg("成功"); msg.setObject(mission); msgList.add(msg); mission=null; //entryList.clear(); } } catch (Exception e) { e.printStackTrace(); return Msg.defineFail("錯誤")+""; } } }
在第一次for迴圈中,重新new了一個entryList,這是個全新的entryList,同時不用再使用entryList.clear()對其清空。因此就不存在修改了ArrayList。
總結:
程式碼簡介之美還得多學學,多看看啊。雖然java的JC機制幫我們做了很多垃圾回收工作,但是在程式中也應該儘量慎重選擇物件的作用域。作用域能小則小,過了那個作用域,物件的引用為空了,JC就對其進行回收,記憶體的堆區不必因為存在太多物件而佔用記憶體。