使用 ConcurrentHashMap的缓存设计,实现基于本地程序内部的小巧的缓存工具类,具备缓存时效核查,缓存时效删除等功能。设计思路,系统设置两个ConcurrentHashMap变量,一个用来存放我们的value值,一个用来存放vlaue对于的缓存有效时间。系统通过TimerTask定时器,核查是否有过期的key,若过期从缓存中清除。代码如下
package com.zhegui.utils.cache;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
/**
* 基于ConcurrentHashMap的缓存工具类
* 主要目的: 模拟内存缓存
* @author Zhegui
*
*/
public class ConcurrentHashMapCache {
private ConcurrentHashMapCache(){}
private static class InnerHolder{
private static ConcurrentHashMapCache instance = new ConcurrentHashMapCache();
static{
CACHE_VALUE = new ConcurrentHashMap<>();
CACHE_TIME = new ConcurrentHashMap<>();
cacheTimer();
}
/**
* 设定一个定时器
*/
private static void cacheTimer(){
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
System.out.println("start chedule....");
for (String key : CACHE_TIME.keySet()) {
Long mapLong = CACHE_TIME.get(key);
if(mapLong !=null && mapLong < System.currentTimeMillis()){
CACHE_VALUE.remove(CACHE_PRX+key);
CACHE_TIME.remove(CACHE_PRX+key);
System.out.println("remove key:"+key);
}
}
}
}, 10 * 1000 , 2 * 60 * 1000);
}
}
public static ConcurrentHashMapCache getInstance(){
return InnerHolder.instance;
}
/**
* 默认缓存key的前缀
*
*/
private static final String CACHE_PRX = "default:";
/**
* 默认缓存时间
*/
private static final long DEFAULT_TIME = 5 * 60 * 1000;
/**
* 缓存一分钟
*/
public static final long ONE_MINUTE = 60 * 1000;
/**
* 默认缓存时间 30分钟
*/
public static final long HALF_HOUR = 30 * 60 * 1000;
/**
* 一个小时
*/
public static final long ONE_HOUR = 60 * 60 * 1000;
/**
* 半天
*/
public static final long HALF_DAY = 12 * 60 * 60 * 1000;
/**
* 缓存一个小时
*/
public static final long ONE_DAY = 2 * HALF_DAY;
/**
* 用来缓存真正的值
*/
private static Map<String, String> CACHE_VALUE = null;
/**
* 用来缓存时间
*/
private static Map<String, Long> CACHE_TIME = null;
/**
* 默认缓存时间为5分钟
* @param key
* @param value
*/
public void put(String key, String value){
put(key, value, DEFAULT_TIME);
}
/**
* 存入缓存
* @param key
* @param value
* @param time
*/
public void put(String key, String value, long time){
if(key == null || "".equals(key)){
throw new IllegalArgumentException("key is not allow null or '' ");
}
if(time < 0){
throw new IllegalArgumentException("time must more than 0 '' ");
}
CACHE_VALUE.put(CACHE_PRX + key, value);
CACHE_TIME.put(CACHE_PRX + key, System.currentTimeMillis() + time);
}
/**
* 删除缓存
* @param key
*/
public void remove(String key){
CACHE_VALUE.remove(CACHE_PRX+key);
CACHE_TIME.remove(CACHE_PRX+key);
}
/**
* 获取缓存的数据
* @param key
* @return
*/
public String get(String key){
String result = null;
if(key == null || "".equals(key)){
return result;
}
Long mapLong = CACHE_TIME.get(CACHE_PRX + key);
if(mapLong != null && mapLong < System.currentTimeMillis()){
this.remove(key);
}else{
result = CACHE_VALUE.get(CACHE_PRX + key);
}
return result;
}
}
编写客户端代码
package com.zhegui.utils.cache;
public class CacheClientTest {
public static void main(String[] args) throws InterruptedException {
ConcurrentHashMapCache cache = ConcurrentHashMapCache.getInstance();
String value = "test3333";
String key = "key1";
cache.put(key, value);
String key2 = "key2";
String value2 = "value222";
cache.put(key2, value2, 30 * 1000);
String key3 = "key3";
String value3 = "value33333333";
cache.put(key3, value3, 2 * 60 * 1000);
Thread.sleep(60 * 1000);
System.out.println("key1: value = "+cache.get(key));
System.out.println("key2: value2 = " + cache.get(key2));
System.out.println("key3: value3 = " + cache.get(key3));
System.out.println("-------remove key1 --------");
cache.remove(key);
System.out.println("key1: value = "+cache.get(key));
System.out.println("key2: value2 = " + cache.get(key2));
System.out.println("key3: value3 = " + cache.get(key3));
Thread.sleep(90 * 1000);
System.out.println("key3: value3 = " + cache.get(key3));
}
}
测试结果如下
总结
ConcurrentHashMap的并发读写速度很快,而且是线程安全的。为何ConcurrentHashMap速度如此之快,可以参考这里链接内容