MemoryCache 缓存 实用

复制代码
MemoryCache 缓存 实用,相关逻辑代码里已详细注释,
在Java中创建一个单例模式(Singleton Pattern)的MyMemoryCache类,可以采用多种方法,其中最常见的是使用“饿汉式”和“懒汉式”(线程安全和非线程安全)的方法。这里,我将向你展示一个线程安全的“懒汉式”实现,使用双重检查锁定(double-checked locking)来确保线程安全和性能。
直接上代码。
复制代码
import java.util.ArrayList;
import java.util.HashMap;

/**
 * Description: [MemoryCache 缓存]
 * </p>
 *
 * @author xx
 */
public class MyMemoryCache<E> {
    // 使用volatile关键字确保多线程环境下的正确可见性
    private static volatile MyMemoryCache instance;

    // 缓存数据的Map
    private HashMap<String, ArrayList<E>> cache;

    // 私有构造方法,防止外部实例化
    private MyMemoryCache() {
        this.cache = new HashMap<>();
    }

    // 提供一个公共的静态方法获取单例
    public static MyMemoryCache getInstance() {
        // 第一次检查,如果instance为null,才进入同步代码块
        if (instance == null) {
            synchronized (MyMemoryCache.class) {
                // 第二次检查,确保只有一个线程创建实例
                if (instance == null) {
                    instance = new MyMemoryCache<>();
                }
            }
        }
        return instance;
    }
    /**
     * 每次添加数据时,如果键已存在则将新对象添加到对应的列表中,否则创建新的列表并添加对象
     * @param key
     * @param value
     */
    public void put(String key, E value) {
        ArrayList<E> list;
        if (cache.containsKey(key)) {
            list = cache.get(key);
        } else {
            list = new ArrayList<>();
        }
        list.add(value);
        cache.put(key, list);
    }
    /**
     * 获取key 全部数据并删除缓存中key数据
     * @return
     */
    public ArrayList<E> getKeyValuesAndClear(String key) {
        ArrayList<E> allData = cache.get(key);
        cache.remove(key);
        return allData;
    }

    /**
     * 获取全部数据并删除缓存中数据
     * @return
     */
    public HashMap<String, ArrayList<E>> getAllAndClear() {
        HashMap<String, ArrayList<E>> allData = new HashMap<>(cache);
        cache.clear();
        return allData;
    }
}

上述代码中,MyMemoryCache类通过私有构造函数和getInstance方法实现了单例模式。volatile关键字确保了在多线程环境中,instance变量的写操作对其他线程是可见的。双重检查锁定(DCL)确保了即使在多线程环境下也只会创建一个实例,并且提高了性能,因为只有在第一次实例化时才需要进入同步代码块。

相关推荐
Java成神之路-3 分钟前
Spring AI Alibaba 实现多轮对话记忆:ChatMemory 与 Redis 持久化实战
java·springaialibaba
JAVA面经实录9176 分钟前
网络编程基础(Java Web/分布式前置·完整版)(十一)
java·前端·网络
W_3260012 分钟前
Python 常用标准 / 第三方库:random、tqdm、turtle、jieba 用法
开发语言·python
Escalating_xu19 分钟前
【Linux】基础 I/O 深度解析:FILE、文件描述符、open/read/write、重定向与缓冲区
java·linux·服务器
城管不管22 分钟前
MySQL 慢查询完整排查
java·服务器·jvm·数据库·mysql·spring·面试
ZC跨境爬虫34 分钟前
LeetCode 88. 合并两个有序数组(双指针详解 + Java Python 实现)
java·python·算法·leetcode
caimouse38 分钟前
ReactOS 图形系统分析(17):区域填充 — EngPaint / IntEngPaint(paint.c)
c语言·开发语言·算法
北风toto1 小时前
研发效能与后端核心技术全景指南:从CI/CD到共性组件实战
java·开发语言·ci/cd
Billy121381 小时前
Day12-C++20 Coroutines(上):协程原理与Promise/Awaitable机制
开发语言·c++进阶学习
01二进制代码漫游日记1 小时前
C++基础入门速通
java·开发语言·c++