初步揭开缓存神秘面纱之双map实现缓存管理的类

在应用程序中,缓存是一种常见的优化手段,可以提高数据的访问速度。针对缓存管理,我们通常会实现一些类来方便地管理缓存数据。缓存具体是如何实现的,这里我们利用双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秒后获取缓存值,验证缓存的过期与移除功能。

输出当前缓存数量,并在删除缓存后再次输出当前缓存数量,以验证删除功能。

复制代码
相关推荐
Yan-英杰9 分钟前
【百日精通JAVA | SQL篇 | 第三篇】 MYSQL增删改查
java·数据库·sql
矛取矛求1 小时前
C++ 标准库参考手册深度解析
java·开发语言·c++
cijiancao1 小时前
23 种设计模式中的解释器模式
java·设计模式·解释器模式
南七行者2 小时前
对模板方法模式的理解
java·设计模式·模板方法
遥不可及~~斌2 小时前
关于 @Autowired 和 @Value 使用 private 字段的警告问题分析与解决方案
spring·springboot
麻芝汤圆2 小时前
MapReduce 的广泛应用:从数据处理到智能决策
java·开发语言·前端·hadoop·后端·servlet·mapreduce
努力的搬砖人.2 小时前
java如何实现一个秒杀系统(原理)
java·经验分享·后端·面试
哈哈哈哈哈哈哈哈哈...........2 小时前
【java】在 Java 中,获取一个类的`Class`对象有多种方式
java·开发语言·python
fallwind_of_july2 小时前
java项目分享-分布式电商项目附软件链接
java·redis·分布式·mongodb·elasticsearch·微服务·rabbitmq
武昌库里写JAVA2 小时前
Golang的消息中间件选型
java·开发语言·spring boot·学习·课程设计