我设计了一个牛逼的本地缓存!
点击上方 java项目开发,选择 设为星标
优质文章,及时送达
作者:ksfzhaohui
http://dwz.win/Ws4
考虑点
1.数据结构
2.对象上限
3.清除策略
4.过期时间
5.线程安全
6.简明的接口
7.是否持久化
8.阻塞机制
如何实现
1.数据结构
Map<Object, Object> cache = new ConcurrentHashMap<Object, Object>()Mybatis使用HashMap本身是非线程安全的,所以可以看到起内部使用了一个SynchronizedCache用来包装,保证线程的安全性;
2.对象上限
3.清除策略
LRU :Least Recently
Used的缩写最近最少使用,移除最长时间不被使用的对象;常见的使用LinkedHashMap来实现,也是很多本地缓存默认使用的策略;
FIFO :先进先出,按对象进入缓存的顺序来移除它们;常见使用队列Queue来实现;
LFU :Least Frequently
Used的缩写大概也是最近最少使用的意思,和LRU有点像;区别点在LRU的淘汰规则是基于访问时间,而LFU是基于访问次数的;可以通过HashMap并且记录访问次数来实现;
SOFT :软引用基于垃圾回收器状态和软引用规则移除对象;常见使用SoftReference来实现;
WEAK :弱引用更积极地基于垃圾收集器状态和弱引用规则移除对象;常见使用WeakReference来实现;
4.过期时间
被动删除 :每次进行get/put操作的时候都会检查一下当前key是否已经过期,如果过期则删除,类似如下代码:
if (System.currentTimeMillis() - lastClear > clearInterval) {
clear();
}
5.线程安全
public synchronized void putObject(Object key, Object object) {
...省略...
}
@Override
public synchronized Object getObject(Object key) {
...省略...
}
6.简明的接口
public interface Cache {
String getId();
void putObject(Object key, Object value);
Object getObject(Object key);
Object removeObject(Object key);
void clear();
int getSize();
ReadWriteLock getReadWriteLock();
}
public interface Cache<K, V> {
V getIfPresent(@CompatibleWith("K") Object key);
V get(K key, Callable extends V> loader) throws ExecutionException;
ImmutableMapgetAllPresent(Iterable> keys) ;
void put(K key, V value);
void putAll(Map extends K, ? extends V> m);
void invalidate(@CompatibleWith("K") Object key);
void invalidateAll(Iterable> keys);
void invalidateAll();
long size();
CacheStats stats();
ConcurrentMapasMap() ;
void cleanUp();
}
7.是否持久化
diskPersistent="false" //是否持久化磁盘缓存
8.阻塞机制
public class Memoizerl<A, V> implements Computable<A, V> {
private final Map> cache = new ConcurrentHashMap>();
private final Computable c;
public Memoizerl(Computable c) {
this.c = c;
}
@Override
public V compute(A arg) throws InterruptedException, ExecutionException {
while (true) {
Futuref = cache.get(arg);
if (f == null) {
Callableeval = new Callable () {
@Override
public V call() throws Exception {
return c.compute(arg);
}
};
FutureTaskft = new FutureTask (eval);
f = cache.putIfAbsent(arg, ft);
if (f == null) {
f = ft;
ft.run();
}
try {
return f.get();
} catch (CancellationException e) {
cache.remove(arg, f);
}
}
}
}
}
总结
推荐案例
温暖提示
请长按识别二维码
想学习更多的java功能案例请关注
Java项目开发
如果你觉得这个案例以及我们的分享思路不错,对你有帮助,请分享给身边更多需要学习的朋友。别忘了《留言+点在看》给作者一个鼓励哦!
评论