共计 2938 个字符,预计需要花费 8 分钟才能阅读完成。
本地缓存有如下四个经典实现:HashMap, Guava Cache, Caffine, Encache
HashMap
利用 LinkedHashMap 实现 LRU 缓存,示例代码如下:
public class LRUCache extends LinkedHashMap {
/**
* 可重入读写锁,保障并发读写安全性
*/
private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private Lock readLock = readWriteLock.readLock();
private Lock writeLock = readWriteLock.writeLock();
/**
* 缓存大小限度
*/
private int maxSize;
public LRUCache(int maxSize) {super(maxSize + 1, 1.0f, true);
this.maxSize = maxSize;
}
@Override
public Object get(Object key) {readLock.lock();
try {return super.get(key);
} finally {readLock.unlock();
}
}
@Override
public Object put(Object key, Object value) {writeLock.lock();
try {return super.put(key, value);
} finally {writeLock.unlock();
}
}
// 只须要笼罩 LinkedHashMap 的 removeEldestEntry 办法,便可实现 LRU 淘汰策略
@Override
protected boolean removeEldestEntry(Map.Entry eldest) {return this.size() > maxSize;
}
}
Guava Cache
特点 :
- 反对最大容量限度。
- 反对两种过期删除策略(插入工夫和拜访工夫)。
- 基于 LRU 淘汰算法。
- 反对简略的统计性能。
示例代码如下:
public class GuavaCacheTest {public static void main(String[] args) throws Exception {
// 创立 guava cache
Cache<String, String> loadingCache = CacheBuilder.newBuilder()
//cache 的初始容量
.initialCapacity(5)
//cache 最大缓存数
.maximumSize(10)
// 设置写缓存后 n 秒钟过期
.expireAfterWrite(17, TimeUnit.SECONDS)
// 设置读写缓存后 n 秒钟过期, 理论很少用到, 相似于 expireAfterWrite
//.expireAfterAccess(17, TimeUnit.SECONDS)
.build();
String key = "key";
// 往缓存写数据
loadingCache.put(key, "v");
// 获取 value 的值,如果 key 不存在,调用 collable 办法获取 value 值加载到 key 中再返回
String value = loadingCache.get(key, new Callable<String>() {
@Override
public String call() throws Exception {return getValueFromDB(key);
}
});
// 删除 key
loadingCache.invalidate(key);
}
private static String getValueFromDB(String key) {return "v";}
}
Caffeine
特点 :
- 是 Guava Cache 的增强版,性能更优。
- 基于联合 LRU, LFU 的淘汰算法:W-TinyLFU。
示例代码如下:
public class CaffeineCacheTest {public static void main(String[] args) throws Exception {
// 创立 guava cache
Cache<String, String> loadingCache = Caffeine.newBuilder()
//cache 的初始容量
.initialCapacity(5)
//cache 最大缓存数
.maximumSize(10)
// 设置写缓存后 n 秒钟过期
.expireAfterWrite(17, TimeUnit.SECONDS)
// 设置读写缓存后 n 秒钟过期, 理论很少用到, 相似于 expireAfterWrite
//.expireAfterAccess(17, TimeUnit.SECONDS)
.build();
String key = "key";
// 往缓存写数据
loadingCache.put(key, "v");
// 获取 value 的值,如果 key 不存在,获取 value 后再返回
String value = loadingCache.get(key, CaffeineCacheTest::getValueFromDB);
// 删除 key
loadingCache.invalidate(key);
}
private static String getValueFromDB(String key) {return "v";}
}
Encache
特点 :
- 纯 java 的过程内缓存框架。
- 是 Hibernate 中默认的 Cache Provider。
- 反对 FIFO, LRU, LFU 淘汰算法。
- 反对堆内存储、堆外存储和磁盘存储(长久化)。
- 反对多种集群计划,解决数据共享问题。
示例代码如下:
public class EncacheTest {public static void main(String[] args) throws Exception {
// 申明一个 cacheBuilder
CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
.withCache("encacheInstance", CacheConfigurationBuilder
// 申明一个容量为 20 的堆内缓存
.newCacheConfigurationBuilder(String.class,String.class, ResourcePoolsBuilder.heap(20)))
.build(true);
// 获取 Cache 实例
Cache<String,String> myCache = cacheManager.getCache("encacheInstance", String.class, String.class);
// 写缓存
myCache.put("key","v");
// 读缓存
String value = myCache.get("key");
// 移除换粗
cacheManager.removeCache("myCache");
cacheManager.close();}
}
四种本地缓存性能比拟
论断 :本地缓存优先思考:Caffine。
参考文献
https://juejin.cn/post/684490…
正文完