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)确保了即使在多线程环境下也只会创建一个实例,并且提高了性能,因为只有在第一次实例化时才需要进入同步代码块。