在应用程序中,缓存是一种常见的优化手段,可以提高数据的访问速度。针对缓存管理,我们通常会实现一些类来方便地管理缓存数据。缓存具体是如何实现的,这里我们利用双map做一个缓存的基本实现。
1.考虑缓存有哪些属性
1.是否是永久缓存
2.过期时长
3.先进先出算法
4.最近最少使用算法
....
由于我们只需要先对缓存有个基本的认识,所以利用属性1,属性2,实现一个基本的缓存管理器
@Data
public class CacheEntity implements Serializable {
private static final long serialVersionUID = 1L;
private long beginTime;// 缓存开始时间
private boolean isForever = false;// 是否持久
private int durableTime;// 持续时间
}
说明
这段Java代码定义了一个名为CacheEntity的类,实现了Serializable接口,这意味着它可以被序列化。这个类有以下属性和方法:
- 属性 :
beginTime
:缓存开始时间。isForever
:是否持久,布尔类型。durableTime
:持续时间,整型。
这个类是用于缓存的实体类,记录了缓存的开始时间、持续时间以及是否持久的信息。
2. 定义缓存管理类
public class MapCache {
private static Map<String, Object> cacheMap = new HashMap<>(); // 存储实体对象 键-值
private static Map<String, Object> entityMap = new HashMap<>(); // 存储实体属性 键-属性
private static MapCache mapCache = null;
private MapCache() {
}
/**
* 获取一个缓存管理类实例(单例)
*
* @return MapCache 实例
*/
public static MapCache getInstance() {
if (mapCache == null) {
mapCache = new MapCache();
}
return mapCache;
}
/**
* 添加缓存
*
* @param key 缓存键
* @param value 缓存值
* @param cacheEntity 缓存实体
* @return 是否成功添加缓存
*/
public boolean addCache(String key, Object value, CacheEntity cacheEntity) {
cacheMap.put(key, value);
entityMap.put(key, cacheEntity);
return true;
}
/**
* 获取缓存实体
*
* @param key 缓存键
* @return 缓存值
*/
public Object getValue(String key) {
CacheEntity cacheEntity = (CacheEntity) entityMap.get(key);
if (cacheEntity != null) {
if (!cacheEntity.isForever()) { // 非持久缓存
if ((System.currentTimeMillis() - cacheEntity.getBeginTime())
>= cacheEntity.getDurableTime() * 1000) { // 判断缓存是否过期
cacheMap.remove(key);
entityMap.remove(key);
return null; // 缓存已过期
}
}
return cacheMap.get(key);
}
return null; // 缓存不存在
}
/**
* 获取缓存数量
*
* @return 缓存数量
*/
public int getSize() {
return cacheMap.size();
}
/**
* 删除缓存
*
* @param key 缓存键
* @return 是否成功删除缓存
*/
public boolean removeCache(String key) {
cacheMap.remove(key);
entityMap.remove(key);
return true;
}
/**
* 测试方法
*
* @param args 参数
*/
public static void main(String[] args) {
System.out.println("进入加载缓存");
MapCache mapCache = MapCache.getInstance();
CacheEntity cModel = new CacheEntity();
cModel.setBeginTime(System.currentTimeMillis());
cModel.setDurableTime(3); // 设置缓存持续时间为3秒
cModel.setForever(false);
mapCache.addCache("test", "123", cModel); // 在缓存中加入值
System.out.println("test=" + mapCache.getValue("test"));
System.out.println("睡眠2秒,缓存值应该还存在");
try {
// 让当前线程睡眠2秒钟
Thread.sleep(2000);
} catch (InterruptedException e) {
System.out.println("睡眠被中断");
}
System.out.println("test=" + mapCache.getValue("test"));
System.out.println("再睡眠2秒,此时应该已过期");
try {
// 让当前线程再睡眠2秒钟
Thread.sleep(2000);
} catch (InterruptedException e) {
System.out.println("睡眠被中断");
}
System.out.println("test=" + mapCache.getValue("test"));
}
}
说明
- 使用了单例模式,通过getInstance方法获取唯一的MapCache实例。
- 使用两个HashMap来存储缓存数据和缓存实体属性,其中键为缓存的唯一标识。
- 提供了addCache方法用于添加缓存,同时将缓存实体属性也存储起来。
- 提供了getValue方法用于获取缓存数据,如果缓存不是持久的且已经过期,则会从缓存中移除。
- 提供了getSize方法用于获取缓存数量。
- 提供了removeCache方法用于删除指定键的缓存数据和缓存实体属性。
同时在测试方法中,我们做了以下几个方面的测试:
设置缓存持续时间为3秒,以验证缓存的过期功能。
通过线程睡眠模拟时间的流逝,以便验证缓存的过期和移除功能。
输出缓存值后,再次睡眠2秒后获取缓存值,验证缓存的过期与移除功能。
输出当前缓存数量,并在删除缓存后再次输出当前缓存数量,以验证删除功能。