HashMap 或者 ConcurrentHashMap
是在Java 中使用最简单的本地缓存方式。ConcurrentHashMap多用于缓存更新的场景,因为它是线程安全的,可以保证数据的一致性。
LinkedHashMap类
提供了一个==自动清理最老元素==的功能,可以作为一个LRU(Least Recently Used ,表示最近最少使用)缓存使用。
将LinkedHashMap 改造成缓存
需要重写 LinkedHashMap 中 removeEldestEntry(Map.Entry<K,V> eldest) 这个方法。
默认返回false,不移除老的key,需要开发人员自己改造。
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
return false;
}
自定义MyLruCache,来实现一个自动清理老数据,将热数据放在队尾。
package com.wuxiongwei.java.hashmap.linkedhashmap;
import java.util.LinkedHashMap;
public class MyLruCache<K, V> extends LinkedHashMap<K, V>
{
private static final long serialVersionUID = 4504158311663914052L;
@Override
public V put(K key, V value) {
//或者Map<String, String> cache = Collections.synchronizedMap(new LruCache<String, String>(3));
// synchronized (this) {
return super.put(key, value);
// }
}
private int maxCacheSize;
public MyLruCache(int maxCacheSize) {
// 第三个参数为 accessOrder,默认为false。
// 表示按照按照访问顺序排列元素,最近访问的元素会排在队末尾
super(maxCacheSize, 0.75f, true);
this.maxCacheSize = maxCacheSize;
}
@Override
protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
//默认返回false,队列会越来越大
// 当达到预设缓存上限时删除最老元素
return this.size() >= maxCacheSize + 1;
}
}
package com.wuxiongwei.java.hashmap.linkedhashmap;
import java.util.HashMap;
import java.util.Map;
public class Clinet1 {
public static void main(String[] args) {
MyLruCache<String, String> cache = new MyLruCache<String, String>(3);
//如果MyLruCache本身不是线程安全的,可以使用Collections.synchronizedMap来打到线程安全的效果
//Map<String, String> cache = Collections.synchronizedMap(new MyLruCache<String, String>(3));
//初始化三个key
cache.put("k1", "v1");
System.out.println("put1:"+cache);
cache.put("k2", "v2");
System.out.println("put2:"+cache);
cache.put("k3", "v3");
System.out.println("put3:"+cache);
//因为大小是3,添加第四个时会移除k1
cache.put("k4", "v4");
System.out.println("put4:"+cache);
//访问一次 k2,k2对应的元素就会排在队尾部,被看做最新元素
cache.get("k2");
System.out.println("get5:"+cache);
Map<String,String> multiKV = new HashMap<String,String>();
multiKV.put("k5", "k5");
multiKV.put("k6", "k6");
cache.putAll(multiKV);
System.out.println("get6:"+cache);
}
}
输出结果
put1:{k1=v1}
put2:{k1=v1, k2=v2}
put3:{k1=v1, k2=v2, k3=v3}
put4:{k2=v2, k3=v3, k4=v4}
get5:{k3=v3, k4=v4, k2=v2}
get6:{k2=v2, k5=k5, k6=k6}