JDK1.4 的ConcurrentModificationException异常

问题代码:


/**
 * @version 1.0 缓存用户信息的工具类。
 */
public class PrivilegeManager extends AbstractDomainEntity {

    static final long serialVersionUID = 1288L;
    
    /**
	 * 缓存用户信息的HashMap。 Key为UID,Value为EGISStaff
	 */
	//private static Map usersCacheMap = Collections.synchronizedMap(new HashMap());
	private static Map usersCacheMap = new HashMap();
    private Object o = new Object();
	/**
	 * @roseuid 43BEBB810000
	 */
	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);
        }
	}

    /**
     * 获取缓存中所有的用户信息
     * @return 包含若干EGISStaffDTO的List
     */
    public List getAllEGISStaffs()
    {
        List staffs = new ArrayList();
        //List removableUsers = new ArrayList();
        synchronized (o) {
            Set keysSet = usersCacheMap.keySet();
            Iterator keysIterator = keysSet.iterator();

            // 获取缓存中所有用户,若缓存时间超过5分钟则不获取
            while (keysIterator.hasNext()) {
                String uid = (String) keysIterator.next();
                CacheRecord cachestaff = (CacheRecord) usersCacheMap.get(uid);
                if (cachestaff != null) {
                    //if (System.currentTimeMillis() - cachestaff.getCreateTime() > 5 * 60 * 1000) {
                    //    removableUsers.add(uid);
                    //}
                    //else {
                    EGISStaffDTO staff = ((EGISStaff) cachestaff.getValue()).getTheEGISStaffDTO();
                    staffs.add(staff);
                    //}
                }
            }
            // 将缓存时间超过5分钟的用户清除出缓存,这里要单独拿出来删除,不能再循环里面,否则会报java.util.ConcurrentModificationException
            //for (int i = 0; i < removableUsers.size(); i++)
            //    usersCacheMap.remove(removableUsers.get(i));
        }

        return staffs;
    }
}



异常信息



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可以保证数据一致性。



你可能感兴趣的:(JDK1.4 的ConcurrentModificationException异常)