最近项目要引入缓存机制,但是不想引入分布式的缓存框架,所以自己就写了一个轻量级的缓存实现,有两个版本,一个是通过timer实现其超时过期处理,另外一个是通过list轮询。
首先要了解下java1.6中的ConcurrentMap ,他是一个线程安全的Map实现,特别说明的是在没有特别需求的情况下可以用ConcurrentHashMap。我是想学习一下读写锁的应用,就自己实现了一个SimpleConcurrentHashMap.
缓存对象CacheEntity.Java为:
- package com.cttc.cache.entity;
-
- import java.io.Serializable;
-
- public class CacheEntity implements Serializable{
- private static final long serialVersionUID = -3971709196436977492L;
- private final int DEFUALT_VALIDITY_TIME = 20;//默认过期时间 20秒
-
- private String cacheKey;
- private Object cacheContext;
- private int validityTime;//有效期时长,单位:秒
- private long timeoutStamp;//过期时间戳
-
- private CacheEntity(){
- this.timeoutStamp = System.currentTimeMillis() + DEFUALT_VALIDITY_TIME * 1000;
- this.validityTime = DEFUALT_VALIDITY_TIME;
- }
-
- public CacheEntity(String cacheKey, Object cacheContext){
- this();
- this.cacheKey = cacheKey;
- this.cacheContext = cacheContext;
- }
-
- public CacheEntity(String cacheKey, Object cacheContext, long timeoutStamp){
- this(cacheKey, cacheContext);
- this.timeoutStamp = timeoutStamp;
- }
-
- public CacheEntity(String cacheKey, Object cacheContext, int validityTime){
- this(cacheKey, cacheContext);
- this.validityTime = validityTime;
- this.timeoutStamp = System.currentTimeMillis() + validityTime * 1000;
- }
-
- public String getCacheKey() {
- return cacheKey;
- }
- public void setCacheKey(String cacheKey) {
- this.cacheKey = cacheKey;
- }
- public Object getCacheContext() {
- return cacheContext;
- }
- public void setCacheContext(Object cacheContext) {
- this.cacheContext = cacheContext;
- }
- public long getTimeoutStamp() {
- return timeoutStamp;
- }
- public void setTimeoutStamp(long timeoutStamp) {
- this.timeoutStamp = timeoutStamp;
- }
- public int getValidityTime() {
- return validityTime;
- }
- public void setValidityTime(int validityTime) {
- this.validityTime = validityTime;
- }
- }
List缓存处理对象:
Timer方式
- package com.cttc.cache.handler;
-
- import java.util.HashMap;
- import java.util.Timer;
- import java.util.TimerTask;
-
- import com.cttc.cache.entity.CacheEntity;
- import com.cttc.cache.entity.SimpleConcurrentMap;
-
- public class CacheTimerHandler {
- private static final long SECOND_TIME = 1000;
- private static final int DEFUALT_VALIDITY_TIME = 20;
- private static final Timer timer ;
- private static final SimpleConcurrentMap<String, CacheEntity> map;
-
- static{
- timer = new Timer();
- map = new SimpleConcurrentMap<String, CacheEntity>(new HashMap<String, CacheEntity>(1<<18));
- }
-
-
- public static void addCache(String key, CacheEntity ce){
- addCache(key, ce, DEFUALT_VALIDITY_TIME);
- }
-
-
- public static synchronized void addCache(String key, CacheEntity ce, int validityTime){
- map.put(key, ce);
-
- timer.schedule(new TimeoutTimerTask(key), validityTime * SECOND_TIME);
- }
-
-
- public static synchronized CacheEntity getCache(String key){
- return map.get(key);
- }
-
-
- public static synchronized boolean isConcurrent(String key){
- return map.containsKey(key);
- }
-
-
- public static synchronized void removeCache(String key){
- map.remove(key);
- }
-
-
- public static int getCacheSize(){
- return map.size();
- }
-
-
- public static synchronized void clearCache(){
- if(null != timer){
- timer.cancel();
- }
- map.clear();
- System.out.println("clear cache");
- }
-
-
- static class TimeoutTimerTask extends TimerTask{
- private String ceKey ;
-
- public TimeoutTimerTask(String key){
- this.ceKey = key;
- }
-
- @Override
- public void run() {
- CacheTimerHandler.removeCache(ceKey);
- System.out.println("remove : "+ceKey);
- }
- }
- }
timer方式有点是适用性更强,因为每个缓存的过期时间都可以独立配置的;ist只能适用于缓存时间都一样的线性过期。从性能开销方面,因为timer是与缓存对象数量成正比的,在缓存量很大的时候,在缓存时间内系统开销也随之提高;而list方式只要一个线程管理过期清理就可以了。
这里要感谢饭饭泛,从其微博学习到很多http://www.blogjava.net/xylz/archive/2010/07/14/326080.html
java cache过期策略两种实现,一个基于list轮询一个基于timer定时
原文:http://www.cnblogs.com/firstdream/p/5515090.html