自定义缓存
今天测试了照着网上的缓存写了一个简单的缓存功能。总体来说还是有很多感触的,以前很少用到多线程,这次才发现多线程也可以用到缓存上。。。。
-
定义缓存
首先定义一个缓存类,很简单—–一个key一个value再加一个过期时间。代码如下
package com.clear;
/**
* @author: CLEARLi
* @date: 2020/4/5
* @description 一般类
*/
public class Cache {
private String key;
private Object value;
//有效期
private Long timeout;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public Long getTimeout() {
return timeout;
}
public void setTimeout(Long timeout) {
this.timeout = timeout;
}
}
-
创建缓存处理对象
缓存的主要思想,就是创建一个线程池,将要缓存的对象放入线程池中。使用定时线程定时检查缓存的对象是否超时。难点主要有两个。1.判断是否超时。2.线程池的创建和使用 。3.使用同步方法(容易被忽视)。
下面是代码
package com.clear;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @author: CLEARLi
* @date: 2020/4/5
* @description 提供缓存api
*/
public class CacheManager {
//存放缓存数据
private Map<String ,Cache> cacheMap = new HashMap<>();
public void put(String key, Object value) {
put(key, value, null);
}
public synchronized void put(String key,Object value,Long timeout){
Cache cache = new Cache();
cache.setKey(key);
cache.setValue(value);
if (timeout!=null){
cache.setTimeout(System.currentTimeMillis()+timeout);
cacheMap.put(key,cache);
}
}
public synchronized void del(String key){
cacheMap.remove(key);
}
/**
* 无建议(默认)
* @description 使用key查询缓存
* @author ClearLi
* @date 2020/4/6 14:54
* @param key
* @return java.lang.Object
*/
public synchronized Object get(String key){
Cache cache = cacheMap.get(key);
if (cache!=null){
return cache.getValue();
}
return null;
}
public synchronized void remove(String key){
System.out.println("调用删除");
cacheMap.remove(key);
}
/**
* 无建议(默认)
* @description 定期检查有效期的值
* @author ClearLi
* @date 2020/4/6 15:04
* @param
* @return void
*/
public synchronized void checkValidityData(){
System.out.println("检查开始");
for (String key : cacheMap.keySet()) {
//System.out.println(key);
Cache cache = cacheMap.get(key);
if (cache==null){
break;
}
//检查有效期
//之前存放的毫秒数
Long timeout = cache.getTimeout();
// System.out.println("之前的time"+timeout);
//计算时间差
Long currentTimeMillis = System.currentTimeMillis();
if ((currentTimeMillis-timeout)>0){
remove(key);
}
}
}
public static void main(String[] args) {
CacheManager cacheManager = new CacheManager();
cacheManager.put("userName","123",5000L);
//开启一个线程定期刷新
ScheduledExecutorService executorServicePool = Executors.newScheduledThreadPool(5);
executorServicePool.schedule(new Runnable() {
@Override
public void run() {
cacheManager.checkValidityData();
}
},5000, TimeUnit.MILLISECONDS);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(cacheManager.get("userName"));
}
}
总体来说要考虑线程安全问题,和缓存判断失效两点问题。除了使用同步方法之外也可以使用线程安全的 Hashtable或者使用比较推荐的ConcurrentHashMap。