简单本地缓存实现

在项目中有时需要用到本地缓存来存储一些临时数据,如果不考虑分布式的问题,可以自己来实现

1、首先定义一个缓存对象,该对象包含缓存的键,值、失效时间戳、有效时长

package cn.com.mycache;

import java.io.Serializable;

/**
 * 本地缓存对象
 * 
 * @Description: TODO
 * @author wenminggao
 * @date 2015年5月27日 下午5:17:36
 *
 */
public class LocalCacheEntity implements Serializable {
	private static final long serialVersionUID = -3971709196436977492L;
	private final int DEFUALT_VALIDITY_TIME = 20;// 默认过期时间 20秒

	private String cacheKey; // 缓存key
	private Object cacheContent; // 缓存内容
	private int validityTime;// 有效期时长,单位:秒
	private long timeoutStamp;// 过期时间戳

	private LocalCacheEntity() {
		this.timeoutStamp = System.currentTimeMillis() + DEFUALT_VALIDITY_TIME * 1000;
		this.validityTime = DEFUALT_VALIDITY_TIME;
	}

	/**
	 * @param cacheKey
	 * @param cacheContent
	 */
	public LocalCacheEntity(String cacheKey, Object cacheContent) {
		this();
		this.cacheKey = cacheKey;
		this.cacheContent = cacheContent;
	}

	public String getCacheKey() {
		return cacheKey;
	}

	public void setCacheKey(String cacheKey) {
		this.cacheKey = cacheKey;
	}

	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;
	}

	public Object getCacheContent() {
		return cacheContent;
	}

	public void setCacheContent(Object cacheContent) {
		this.cacheContent = cacheContent;
	}
}

2、定义缓存处理器

package cn.com.mycache;

import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 缓存处理器
 * 
 * @Description: TODO
 * @author wenminggao
 * @date 2015年5月27日 下午5:20:02
 *
 */
public class LocalCacheHandler {
	private static final long SECOND_TIME = 1000;// 默认过期时间 20秒
	private static final int DEFUALT_VALIDITY_TIME = 20;// 默认过期时间 20秒
	private static final Timer timer;
	private static final ConcurrentHashMap<String, LocalCacheEntity> map;

	static {
		timer = new Timer();
		map = new ConcurrentHashMap<String, LocalCacheEntity>(new HashMap<String, LocalCacheEntity>(1 << 20));
	}

	/**
	 * 增加缓存对象(默认失效时间20秒)
	 * 
	 * @param key
	 * @param ce
	 */
	public static void addCache(LocalCacheEntity localCacheEntity) {
		addCache(localCacheEntity, DEFUALT_VALIDITY_TIME);
	}

	/**
	 * 增加缓存对象
	 * 
	 * @param key
	 * @param ce
	 * @param validityTime
	 *            有效时间
	 */
	public static synchronized void addCache(LocalCacheEntity localCacheEntity, int validityTime) {
		map.put(localCacheEntity.getCacheKey(), localCacheEntity);
		// 添加过期定时
		timer.schedule(new TimeoutTimerTask(localCacheEntity.getCacheKey()), validityTime * SECOND_TIME);
	}

	/**
	 * 获取缓存对象
	 * 
	 * @param key
	 * @return
	 */
	public static synchronized LocalCacheEntity getCache(String key) {
		return map.get(key);
	}

	/**
	 * 检查是否含有制定key的缓冲
	 * 
	 * @param key
	 * @return
	 */
	public static synchronized boolean isConcurrent(String key) {
		return map.containsKey(key);
	}

	/**
	 * 删除缓存
	 * 
	 * @param key
	 */
	public static synchronized void removeCache(String key) {
		map.remove(key);
	}

	/**
	 * 获取缓存大小
	 * 
	 * @param 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");
	}

	/**
	 * 缓存失效清除任务
	 * 
	 * @Description: TODO
	 * @author wenminggao
	 * @date 2015年5月27日 下午5:24:40
	 *
	 */
	static class TimeoutTimerTask extends TimerTask {
		private String ceKey;

		public TimeoutTimerTask(String key) {
			this.ceKey = key;
		}

		@Override
		public void run() {
			LocalCacheHandler.removeCache(ceKey);
			System.out.println("remove : " + ceKey);
		}
	}
}

这里用timer来实现过期清除


3、缓存基本也是保存二进制流的,方便存储,也避免对缓存的值进行修改,特别是本地缓存(JAVA是值传递),所以还需要有对象的序列化和反序列化,采用kryo进行

需要在maven中引入依赖

<dependency>
            <groupId>com.esotericsoftware.kryo</groupId>
            <artifactId>kryo</artifactId>
            <version>2.24.0</version>
        </dependency>
package cn.com.mycache;

import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;

/**
 * 缓存处理器
 * 
 * @Description: TODO
 * @author wenminggao
 * @date 2015年5月27日 下午5:20:02
 *
 */
public class LocalCacheHandler {
    private static final long SECOND_TIME = 1000;// 默认过期时间 20秒
    private static final int DEFUALT_VALIDITY_TIME = 20;// 默认过期时间 20秒
    private static final Timer timer;
    private static final ConcurrentHashMap<String, byte[]> map;

    static {
        timer = new Timer();
        map = new ConcurrentHashMap<String, byte[]>(new HashMap<String, byte[]>(1 << 20));
    }

    /**
     * 增加缓存对象(默认失效时间20秒)
     * 
     * @param key
     * @param ce
     */
    public static void addCache(LocalCacheEntity localCacheEntity) {
        addCache(localCacheEntity, DEFUALT_VALIDITY_TIME);
    }

    /**
     * 增加缓存对象
     * 
     * @param key
     * @param ce
     * @param validityTime
     *            有效时间
     */
    public static synchronized void addCache(LocalCacheEntity localCacheEntity, int validityTime) {
        map.put(localCacheEntity.getCacheKey(), serialize(localCacheEntity));
        // 添加过期定时
        timer.schedule(new TimeoutTimerTask(localCacheEntity.getCacheKey()), validityTime * SECOND_TIME);
    }

    /**
     * 获取缓存对象
     * 
     * @param key
     * @return
     */
    public static synchronized LocalCacheEntity getCache(String key) {
        Object obj = deSerialize(map.get(key));
        if (obj instanceof LocalCacheEntity) {
            return (LocalCacheEntity) obj;
        }
        return null;
    }

    /**
     * 检查是否含有制定key的缓冲
     * 
     * @param key
     * @return
     */
    public static synchronized boolean isConcurrent(String key) {
        return map.containsKey(key);
    }

    /**
     * 删除缓存
     * 
     * @param key
     */
    public static synchronized void removeCache(String key) {
        map.remove(key);
    }

    /**
     * 获取缓存大小
     * 
     * @param 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");
    }

    /**
     * 缓存失效清除任务
     * 
     * @Description: TODO
     * @author wenminggao
     * @date 2015年5月27日 下午5:24:40
     *
     */
    static class TimeoutTimerTask extends TimerTask {
        private String ceKey;

        public TimeoutTimerTask(String key) {
            this.ceKey = key;
        }

        @Override
        public void run() {
            LocalCacheHandler.removeCache(ceKey);
            System.out.println("remove : " + ceKey);
        }
    }

    /**
     * 对象序列化
     * 
     * @param value
     * @return
     */
    public static byte[] serialize(Object value) {
        try {
            Kryo kryo = new Kryo();
            byte[] buffer = new byte[2048];
            Output output = new Output(buffer);
            kryo.writeClassAndObject(output, value);
            return output.toBytes();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 对象反序列化
     * 
     * @param value
     * @return
     */
    public static Object deSerialize(byte[] value) {
        try {
            Kryo kryo = new Kryo();
            Input input = new Input(value);
            return kryo.readClassAndObject(input);
        } catch (Exception e) {
            return null;
        }
    }

}


转载于:https://my.oschina.net/gaowm/blog/420694

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值