Java 内部缓存代码(快速简单高效)

84 阅读2分钟

适用场景

  • 短期或临时数据:如本次请求的处理数据、任务中间结果等。
  • 频繁读取、修改的临时缓存:例如一些经常查询的对象、常量数据。
  • 单机应用:没有分布式需求的情况下,适合只需要在单个服务内共享的数据。
  • 小规模数据缓存:当缓存数据量很大时可能会导致应用内存溢出。

特点

  • 存储位置:数据直接存储在应用进程的内存中。
  • 访问速度:访问速度极快,适合频繁访问的短期数据存储。
  • 有效期控制:可以通过代码自定义过期机制。
  • 数据持久性:无数据持久化,重启应用时数据会丢失。
  • 线程安全:可以在多线程环境中使用,通常使用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;
        }
    }
}