在java項目開發中考慮到在使用HashMap在併發時會出現不正確行爲,自己編寫了採用static ConcurrentHashMap來完成靜態緩存的處理,目的是爲了能夠用來處理高併發的線程安全類,如有問題請各指教:
package com.hlwfarm.market.service;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.ctrip.market.commom.CLogger;
import com.ctrip.market.commom.DateTimeUtil;
import com.ctrip.market.commom.Distance;
import com.ctrip.market.commom.ServiceFactory;
import com.ctrip.market.entity.GfMsgscene;
public class MapCacheManager {
private static CLogger<MapCacheManager> logger = new CLogger<MapCacheManager>();
private volatile long updateTime = 0L;// 更新緩存時記錄的時間
private volatile boolean updateFlag = true;// 正在更新時的閥門,爲false時表示當前沒有更新緩存,爲true時表示當前正在更新緩存
private static Map<String, Object> cacheMap = new ConcurrentHashMap<String, Object>();// 緩存容器
private static GfMsgsceneService gfMsgsceneService = (GfMsgsceneService) ServiceFactory
.getInstance("gfMsgsceneService");// 場景信息
public MapCacheManager() {
this.LoadCache();// 加載緩存
updateTime = System.currentTimeMillis();// 緩存更新時間
}
/**
* 裝載緩存
*/
private void LoadCache() {
this.updateFlag = true;// 正在更新
/********** 數據處理,將數據放入cacheMap緩存中 **begin ******/
List<GfMsgscene> sceneList = gfMsgsceneService.queryByDateList();
cacheMap.put("sceneList", sceneList);
cacheMap.put("key2", "value2");
logger.info("更新緩存完成", "更新緩存完成, date=" + DateTimeUtil.GetNowDateString());
System.out.println("更新緩存完成:" + DateTimeUtil.GetNowDateString());
/********** 數據處理,將數據放入cacheMap緩存中 ***end *******/
this.updateFlag = false;// 更新已完成
}
/**
* 返回緩存單個對象
*
* @return
*/
public Object getObjectCache(String key) {
long currentTime = System.currentTimeMillis();
synchronized (this) {
// 如果當前緩存正在更新或者緩存超出時限,需重新加載
if (this.IsTimeOut(currentTime)) {
this.ReLoadCache();
this.updateTime = currentTime;
}
}
return this.cacheMap.get(key);
}
private boolean IsTimeOut(long currentTime) {
logger.info("up", "up=" + (currentTime - this.updateTime));
return ((currentTime - this.updateTime) >= 1000 * 60 * 10);// 超過時限,緩存1分鐘
}
/**
* 獲取緩存項大小
*
* @return
*/
private int getCacheSize() {
return cacheMap.size();
}
/**
* 獲取更新時間
*
* @return
*/
private long getUpdateTime() {
return this.updateTime;
}
/**
* 獲取更新標誌
*
* @return
*/
private boolean getUpdateFlag() {
return this.updateFlag;
}
/**
* 重新裝載
*/
private void ReLoadCache() {
this.cacheMap.clear();
this.LoadCache();
}
/**
* @ClassName: CacheKeyEnum
* @Description: 緩存數據key枚舉
*/
public enum CacheKeyEnum {
sceneList,
}
}
/**
* 返回緩存全部
*
* @return
*/
public Map<String, Object> getMapCache() {
long currentTime = System.currentTimeMillis();
// 如果當前緩存正在更新或者緩存超出時限,需重新加載
if (this.IsTimeOut(currentTime)) {
synchronized (this) {
this.ReLoadCache();
this.updateTime = currentTime;
}
}
return this.cacheMap;
}
單元測試:
public class CacheTest {
private static MapCacheManager cache = new MapCacheManager();
@Test
public void test() {
for (int i = 0; i < 10; i++) {
Map<String, Object> cacheMap = new ConcurrentHashMap<String, Object>();
cacheMap = cache.getMapCache();
Set<String> set = cacheMap.keySet();
Iterator<String> it = set.iterator();
while (it.hasNext()) {
String key = it.next();
System.out.println(key + "=" + JsonSerializer.serialize(cacheMap.get(key)));
}
}
}
}