標籤:code style 建立 equal div 動態 自動 刪除 lang
java.lang.RuntimeException: java.util.ConcurrentModificationException解決方案:
一開始的代碼是這樣的
public static Collection<MailModel> query(MailQuery mailQuery){ List<MailModel> temp = new ArrayList<MailModel>(); Iterator iterator = items.iterator(); while (iterator.hasNext()){ MailModel mm = (MailModel) iterator.next(); if (!mm.getDeptId().equals(mailQuery.getDeptId())){// temp.add(mm); items.remove(mm); } }// items.removeAll(temp); return items; }
至於為什麼報錯呢?
項目中為了擷取Collection中的某個值使用了Iterator,但像List,map等Collection的實現並沒有同步化,如果在多線程應用程式中出現同時訪問,而且出現修改操作的時候都要求外部操作同步化;調用Iterator操作獲得的Iterator對象在多線程修改Set的時候也自動失效,並拋出java.util.ConcurrentModificationException。這種實現機制是fail-fast,對外部的修改並不能提供任何保證。Iterator的工作機制:Iterator是工作在一個獨立的線程中,並且擁有一個 mutex鎖,就是說Iterator在工作的時候,是不允許被迭代的對象被改變的。Iterator被建立的時候,建立了一個記憶體索引表(單鏈表),這 個索引表指向原來的對象,當原來的對象數量改變的時候,這個索引表的內容沒有同步改變,所以當索引指標往下移動的時候,便找不到要迭代的對象,於是產生錯誤。List、Set等是動態,可變對象數量的資料結構,但是Iterator則是單向不可變,只能順序讀取,不能逆序操作的資料結構,當 Iterator指向的未經處理資料發生變化時,Iterator自己就迷失了方向。
如何才能滿足需求呢,需要再定義一個List,用來儲存需要刪除的對象:
public static Collection<MailModel> query(MailQuery mailQuery){ List<MailModel> temp = new ArrayList<MailModel>(); Iterator iterator = items.iterator(); while (iterator.hasNext()){ MailModel mm = (MailModel) iterator.next(); if (!mm.getDeptId().equals(mailQuery.getDeptId())){ temp.add(mm); } } items.removeAll(temp); return items; }
java.lang.RuntimeException: java.util.ConcurrentModificationException