JDK1.4 的ConcurrentModificationException异常处理记录
问题代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 public class PrivilegeManager extends AbstractDomainEntity { static final long serialVersionUID = 1288L ; private static Map usersCacheMap = new HashMap (); private Object o = new Object (); public PrivilegeManager () { } public void setEGISStaff (EGISStaff staff) { usersCacheMap.put(staff.getTheEGISStaffDTO().getUid(), new CacheRecord ( staff)); } public EGISStaff getEGISStaffByUID (String uid) { CacheRecord cachestaff = (CacheRecord) usersCacheMap.get(uid); if (cachestaff != null ) { if (System.currentTimeMillis() - cachestaff.getCreateTime() > 5 * 60 * 1000 ) { usersCacheMap.remove(uid); return null ; } else { return (EGISStaff) cachestaff.getValue(); } } else return null ; } public void removeEGISStaffByUID (String uid) { synchronized (o) { usersCacheMap.remove(uid); } } public List getAllEGISStaffs () { List staffs = new ArrayList (); synchronized (o) { Set keysSet = usersCacheMap.keySet(); Iterator keysIterator = keysSet.iterator(); while (keysIterator.hasNext()) { String uid = (String) keysIterator.next(); CacheRecord cachestaff = (CacheRecord) usersCacheMap.get(uid); if (cachestaff != null ) { EGISStaffDTO staff = ((EGISStaff) cachestaff.getValue()).getTheEGISStaffDTO(); staffs.add(staff); } } } return staffs; } }
异常信息
1 2 3 4 5 com.paic.pafa.core.exceptions.PafaRuntimeException: EJB Exception: ; nested exception is: javax.ejb.EJBException: EJB Exception: : java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextEntry(HashMap.java:782) at java.util.HashMap$KeyIterator.next(HashMap.java:818) at com.palic.egis.support.privilege.common.util.PrivilegeManager.getAllEGISStaffs(PrivilegeManager.java:76)
异常代码:String uid = (String) keysIterator.next();
private static Map usersCacheMap = new HashMap(); 这里在迭代HashMap的KeySet的时候其他线程修改了此HashMap的内容。应该是public EGISStaff getEGISStaffByUID(String uid)中导致的。 修改方案:
1、两个方法都加上同步机制 2、换用 Collections.synchronizedMap(new HashMap()) ,因为是1.4的JDK,需要引入其他JAR包。 3、iterator 的时候删除。iterator可以保证数据一致性。