本地缓存有如下四个经典实现: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...