本文是以LinkedHashMap来实现本地缓存
有人会说,题目不是使用HashMap,怎么又变成LinkedHashMap了
先来说一下为什么不使用HashMap做缓存,而是使用LinkedHashMap。
先来对比一下两者的区别
由于LinkedHashMap维护了一个双向链表来记录所有元素的插入顺序或访问顺序,因此它可以很容易地实现一些基于顺序的缓存策略,例如最近最少使用(LRU)策略。当缓存达到最大容量时,我们可以通过遍历双向链表来找到最近最少使用的元素并将其删除。
而对于普通的HashMap,由于它不维护元素的顺序信息,因此要实现类似的缓存策略会比较困难。我们需要额外维护一个数据结构来记录元素的使用情况,并在缓存达到最大容量时进行相应的删除操作。
因此,使用LinkedHashMap来实现缓存可以更方便地支持基于顺序的缓存策略,而使用普通的HashMap则需要额外的工作
当然还可以选择其他的比如WeakHashMap,ConcurrentHashMap等,来实现本地缓存
这里就以LinkedHashMap为例了
public class TestCache extends LinkedHashMap {
/**
* 设置可重入读写锁,保证并发读写安全性
*/
private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
/**
* 获取读锁
*/
private Lock readLock = readWriteLock.readLock();
/**
* 获取写锁
*/
private Lock writeLock = readWriteLock.writeLock();
/**
* 缓存大小限制
*/
private int maxSize;
/**
* 设置Map的初始容量、加载因子和访问顺序
*/
public TestCache(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();
}
}
@Override
protected boolean removeEldestEntry(Map.Entry eldest) {
return this.size() > maxSize;
}
}
使用Map做缓存,主打的就是实现简单,不需要引入第三方包,适用于一些简单的业务场景。
对于比较复杂的场景,建议使用比较稳定的开源工具。