版权声明:请勿作为商业用途!未经博主允许请勿转载!谢谢支持! https://blog.csdn.net/u012737673/article/details/79295791
Monitor
在框架内部由一个后台的守护线程实现,基于用户的配置定时执行缓存淘汰任务,定义如下:
/**
* 缓存淘汰监控器
*/
public interface Monitor {
void processMonitor();
void start();
void stop();
void startIfStop();
boolean isRunning();
}
当前版本框架提供了2种实现,TtlMonitor和CapMonitor,分别为基于时间策略和基于容量策略。
TtlMonitor
@Override
public void processMonitor() {
long timeNow = System.currentTimeMillis();
for (CacheObject<K, V> o : delegate.values()) {
if (ttl <= 0) {
continue;
}
long timeIdle = timeNow - o.getInitializationTime();
if (timeIdle >= ttl) {
delegate.remove(o.getKey());
for (CacheListener<K, V> listener : listeners) {
listener.callback(new Payload<>(o.getKey(), o.getValue(), o.getInitializationTime()));
}
}
}
}
具体的淘汰策略是后台线程会遍历缓存对象集合,根据其initializationTime属性与currentTime做差值,然后对比ttl,过期者,被移除,并调用CacheListener的callback方法,将被移除对象的相关信息返回给上层。
CapMonitor
@Override
public void processMonitor() {
int size = delegate.size();
if (size >= maximum) {
Map<Long, Object> sortMap = new TreeMap<>();
for (CacheObject<K, V> object : delegate.values()) {
sortMap.put(object.getLastAccessTime(), object.getKey());
}
Set<Long> keySet = sortMap.keySet();
Iterator<Long> it = keySet.iterator();
int count = 0;
int clearSize = (int) (maximum * clearFactor) + size - maximum;
while ((count < clearSize) && it.hasNext()) {
Object v = sortMap.get(it.next());
for (CacheListener<K, V> listener : listeners) {
listener.callback(new Payload<>((K)v,delegate.get(v).getValue(),delegate.get(v).getInitializationTime()));
}
delegate.remove(v);
count++;
}
}
}
基于容量的淘汰策略具体实现是:后台线程先取出当前缓存对象集合的size,如果大于maximum值,将执行淘汰任务。根据缓存对象的lastAccessTime做排序,将“最近使用频率最低的”(maximum * clearFactor) + size - maximum个对象移除掉。例maximum值为100,factor为0.1,当前缓存集合的size为110,则此次移除任务将移除掉100*0.1+110-100,即20个缓存对象。
ps:上层业务再使用时应基于实际业务需求,合理的设置ttl、maximum、factor及interval等参数。例interval值设置的越小,缓存移除的“实时性”及“准确性”就越高,但是系统的开销也会更高。