java實現數據緩存


(轉載請刪除括號里的內容)

緩存是在web開發中經常用到的,將程序經常使用到或調用到的對象存在內存中,或者是耗時較長但又不具有實時性的查詢數據放入內存中,在一定程度上可以提高性能和效率。

創建緩存對象  EntityCache

public class EntityCache {
  /**
   * 保存的數據
   */
  private Object datas;
 
  /**
   * 設置數據失效時間,為0表示永不失效
   */
  private long timeOut;
 
  /**
   * 最后刷新時間
   */
  private long lastRefeshTime;
 
  public EntityCache(Object datas, long timeOut, long lastRefeshTime) {
    this.datas = datas;
    this.timeOut = timeOut;
    this.lastRefeshTime = lastRefeshTime;
  }
  public Object getDatas() {
    return datas;
  }
  public void setDatas(Object datas) {
    this.datas = datas;
  }
  public long getTimeOut() {
    return timeOut;
  }
  public void setTimeOut(long timeOut) {
    this.timeOut = timeOut;
  }
  public long getLastRefeshTime() {
    return lastRefeshTime;
  }
  public void setLastRefeshTime(long lastRefeshTime) {
    this.lastRefeshTime = lastRefeshTime;
  }
 
}

 

定義緩存操作接口  ICacheManager
public interface ICacheManager {
  /**
   * 存入緩存
   * @param key
   * @param cache
   */
  void putCache(String key, EntityCache cache);
 
  /**
   * 存入緩存
   * @param key
   * @param cache
   */
  void putCache(String key, Object datas, long timeOut);
 
  /**
   * 獲取對應緩存
   * @param key
   * @return
   */
  EntityCache getCacheByKey(String key);
 
  /**
   * 獲取對應緩存
   * @param key
   * @return
   */
  Object getCacheDataByKey(String key);
 
  /**
   * 獲取所有緩存
   * @param key
   * @return
   */
  Map<String, EntityCache> getCacheAll();
 
  /**
   * 判斷是否在緩存中
   * @param key
   * @return
   */
  boolean isContains(String key);
 
  /**
   * 清除所有緩存
   */
  void clearAll();
 
  /**
   * 清除對應緩存
   * @param key
   */
  void clearByKey(String key);
 
  /**
   * 緩存是否超時失效
   * @param key
   * @return
   */
  boolean isTimeOut(String key);
 
  /**
   * 獲取所有key
   * @return
   */
  Set<String> getAllKeys();

}

 

實現接口  CacheManagerImpl 實現 ICacheManager
public class CacheManagerImpl implements ICacheManager {
  private static Map<String, EntityCache> caches = new ConcurrentHashMap<String, EntityCache>();
 
  /**
   * 存入緩存
   * @param key
   * @param cache
   */
  public void putCache(String key, EntityCache cache) {
    caches.put(key, cache);
  }
 
  /**
   * 存入緩存
   * @param key
   * @param cache
   */
  public void putCache(String key, Object datas, long timeOut) {
    timeOut = timeOut > 0 ? timeOut : 0L;
    putCache(key, new EntityCache(datas, timeOut, System.currentTimeMillis()));
  }
 
  /**
   * 獲取對應緩存
   * @param key
   * @return
   */
  public EntityCache getCacheByKey(String key) {
    if (this.isContains(key)) {
      return caches.get(key);
    }
    return null;
  }
 
  /**
   * 獲取對應緩存
   * @param key
   * @return
   */
  public Object getCacheDataByKey(String key) {
    if (this.isContains(key)) {
      return caches.get(key).getDatas();
    }
    return null;
  }
 
  /**
   * 獲取所有緩存
   * @param key
   * @return
   */
  public Map<String, EntityCache> getCacheAll() {
    return caches;
  }
 
  /**
   * 判斷是否在緩存中
   * @param key
   * @return
   */
  public boolean isContains(String key) {
    return caches.containsKey(key);
  }
 
  /**
   * 清除所有緩存
   */
  public void clearAll() {
    caches.clear();
  }
 
  /**
   * 清除對應緩存
   * @param key
   */
  public void clearByKey(String key) {
    if (this.isContains(key)) {
      caches.remove(key);
    }
  }
 
  /**
   * 緩存是否超時失效
   * @param key
   * @return
   */
  public boolean isTimeOut(String key) {
    if (!caches.containsKey(key)) {
      return true;
    }
    EntityCache cache = caches.get(key);
    long timeOut = cache.getTimeOut();
    long lastRefreshTime = cache.getLastRefeshTime();
    if (timeOut == 0 || System.currentTimeMillis() - lastRefreshTime >= timeOut) {
      return true;
    }
    return false;
  }
 
  /**
   * 獲取所有key
   * @return
   */
  public Set<String> getAllKeys() {
    return caches.keySet();
  }

}

 

CacheListener 監聽失效數據並移除
public class CacheListener{
  Logger logger = Logger.getLogger("cacheLog");
  private CacheManagerImpl cacheManagerImpl;
  public CacheListener(CacheManagerImpl cacheManagerImpl) {
    this.cacheManagerImpl = cacheManagerImpl;
  }
 
  public void startListen() {
    new Thread(){
      public void run() {
        while (true) {
          for(String key : cacheManagerImpl.getAllKeys()) {
            if (cacheManagerImpl.isTimeOut(key)) {
             cacheManagerImpl.clearByKey(key);
             logger.info(key + "緩存被清除");
           }
          }
        }
      }
    }.start();
 
  }
}

 

測試類 TestCache
public class TestCache {
  Logger logger = Logger.getLogger("cacheLog");
  /**
   * 測試緩存和緩存失效
   */
  @Test
  public void testCacheManager() {
    CacheManagerImpl cacheManagerImpl = new CacheManagerImpl();
    cacheManagerImpl.putCache("test", "test", 10 * 1000L);
    cacheManagerImpl.putCache("myTest", "myTest", 15 * 1000L);
    CacheListener cacheListener = new CacheListener(cacheManagerImpl);
    cacheListener.startListen();
    logger.info("test:" + cacheManagerImpl.getCacheByKey("test").getDatas());
    logger.info("myTest:" + cacheManagerImpl.getCacheByKey("myTest").getDatas());
    try {
      TimeUnit.SECONDS.sleep(20);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    logger.info("test:" + cacheManagerImpl.getCacheByKey("test"));
    logger.info("myTest:" + cacheManagerImpl.getCacheByKey("myTest"));
  }
 
  /**
   * 測試線程安全
   */
  @Test
  public void testThredSafe() {
    final String key = "thread";
    final CacheManagerImpl cacheManagerImpl = new CacheManagerImpl();
    ExecutorService exec = Executors.newCachedThreadPool();
    for (int i = 0; i < 100; i++) {
      exec.execute(new Runnable() {
        public void run() {
            if (!cacheManagerImpl.isContains(key)) {
              cacheManagerImpl.putCache(key, 1, 0);
            } else {
              //因為+1和賦值操作不是原子性的,所以把它用synchronize塊包起來
              synchronized (cacheManagerImpl) {
                int value = (Integer) cacheManagerImpl.getCacheDataByKey(key) + 1;
                cacheManagerImpl.putCache(key,value , 0);
              }
            }
        }
      });
    }
    exec.shutdown();
    try {
      exec.awaitTermination(1, TimeUnit.DAYS);
    } catch (InterruptedException e1) {
      e1.printStackTrace();
    }
 
    logger.info(cacheManagerImpl.getCacheDataByKey(key).toString());
  }

}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM