采用static Map、ConcurrentHashMap实现数据缓存

在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 logger = new CLogger();
  private volatile long updateTime = 0L;// 更新缓存时记录的时间
  private volatile boolean updateFlag = true;// 正在更新时的阀门,为false时表示当前没有更新缓存,为true时表示当前正在更新缓存
  private static Map cacheMap = new ConcurrentHashMap();// 缓存容器

  private static GfMsgsceneService gfMsgsceneService = (GfMsgsceneService) ServiceFactory
      .getInstance("gfMsgsceneService");// 场景信息

  public MapCacheManager() {
    this.LoadCache();// 加载缓存
    updateTime = System.currentTimeMillis();// 缓存更新时间
  }

  /**
   * 装载缓存
   */
  private void LoadCache() {

    this.updateFlag = true;// 正在更新

    /********** 数据处理,将数据放入cacheMap缓存中 **begin ******/

    List 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 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 cacheMap = new ConcurrentHashMap();
      cacheMap = cache.getMapCache();
      Set set = cacheMap.keySet();
      Iterator it = set.iterator();

      while (it.hasNext()) {
        String key = it.next();
        System.out.println(key + "=" + JsonSerializer.serialize(cacheMap.get(key)));
      }
    }
  }

}

你可能感兴趣的:(常用方法,Java)