适用场景:
- 短期或临时数据:如本次请求的处理数据、任务中间结果等。
- 频繁读取、修改的临时缓存:例如一些经常查询的对象、常量数据。
- 单机应用:没有分布式需求的情况下,适合只需要在单个服务内共享的数据。
- 小规模数据缓存:当缓存数据量很大时可能会导致应用内存溢出。
特点:
- 存储位置:数据直接存储在应用进程的内存中。
- 访问速度:访问速度极快,适合频繁访问的短期数据存储。
- 有效期控制:可以通过代码自定义过期机制。
- 数据持久性:无数据持久化,重启应用时数据会丢失。
- 线程安全:可以在多线程环境中使用,通常使用
ConcurrentHashMap等线程安全的数据结构。 - 单机应用:数据只在当前应用实例中有效,不能在不同服务器或实例之间共享数据。
示例:
- 缓存预处理数据(如一段代码中需多次使用的数据)。
- 单一服务器处理请求时共享某些计算结果。
- 临时存储计算结果,以便在相同请求内重用。
内存缓存适合单机的临时数据缓存,跨服务实例的大规模、持久化缓存需求还是建议使用Redis
代码如下可直接copy
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Author:AlanNiew
* Data:2024/11/12 10:44
*/
public class DataCache {
// 内部缓存存储
private static final Map<String, CacheObject> cacheMap = new ConcurrentHashMap<>();
private DataCache() {}
/**
* 添加数据到缓存
*
* @param key 缓存的键
* @param value 缓存的值
* @param ttl 缓存的有效期,单位为毫秒 (ttl <= 0 表示永久有效)
*/
public static void put(String key, Object value, long ttl) {
long expiryTime = ttl > 0 ? System.currentTimeMillis() + ttl : -1;
cacheMap.put(key, new CacheObject(value, expiryTime));
}
/**
* 添加永久有效的数据到缓存
*
* @param key 缓存的键
* @param value 缓存的值
*/
public static void put(String key, Object value) {
put(key, value, -1);
}
/**
* 从缓存中获取数据
*
* @param key 缓存的键
* @return 缓存的数据,若过期或不存在则返回 null
*/
public static Object get(String key) {
CacheObject cacheObject = cacheMap.get(key);
if (cacheObject == null) {
return null;
}
// 检查是否过期
if (cacheObject.isExpired()) {
cacheMap.remove(key); // 数据过期则删除
return null;
}
return cacheObject.getValue();
}
/**
* 从缓存中移除数据
*
* @param key 缓存的键
*/
public static void remove(String key) {
cacheMap.remove(key);
}
/**
* 清空所有缓存
*/
public static void clear() {
cacheMap.clear();
}
/**
* 获取缓存数据数量
*
* @return 缓存的条目数量
*/
public static int size() {
return cacheMap.size();
}
/**
* 检查缓存中是否包含某个键
*
* @param key 缓存的键
* @return 是否包含该键
*/
public static boolean containsKey(String key) {
return cacheMap.containsKey(key);
}
// 内部类,用于封装缓存数据和有效期
private static class CacheObject {
private final Object value;
private final long expiryTime;
CacheObject(Object value, long expiryTime) {
this.value = value;
this.expiryTime = expiryTime;
}
public Object getValue() {
return value;
}
public boolean isExpired() {
return expiryTime > 0 && System.currentTimeMillis() > expiryTime;
}
}
}