Java:多个自刷新缓存对象

Java:多个自刷新缓存对象,java,caching,factory-pattern,Java,Caching,Factory Pattern,我想为多个表创建一个带有工厂的缓存对象。每个缓存都有各自不同的生存时间。例如,城市对象的生存期约为一年,设施列表对象的生存期约为1天 下面是我的缓存类 public abstract class CacheAbstract<E, I, C> { private Long timestamp; private Class<E> entityClass; private Class<I> idClass; private Class<C> cache

我想为多个表创建一个带有工厂的缓存对象。每个缓存都有各自不同的生存时间。例如,城市对象的生存期约为一年,设施列表对象的生存期约为1天

下面是我的缓存类

public abstract class CacheAbstract<E, I, C> {

private Long timestamp;
private Class<E> entityClass;
private Class<I> idClass;
private Class<C> cacheClass;
protected Integer TTL = 60; // In minutes. defaults to 60 mins

private Map<I, C> cache;
private Timer timer;

public CacheAbstract(Class<E> entityClass, Class<I> idClass, Class<C> cacheClass) {
    this.entityClass = entityClass;
    this.idClass = idClass;
    this.cacheClass = cacheClass;
}

public Boolean isExpired() {
    return (this.timestamp + TTL * 60000) < new Date().getTime();
}

private void verifyCache() {
    if (this.cache == null || isExpired()) {
        this.load();
    }
}

private void onTimer() {
    this.timer = new Timer();
    timer.schedule(new TimerTask() {

        @Override
        public void run() {
            throw new UnsupportedOperationException("Not supported yet."); //What should I do here? I can't call this class' load(), can I?;
        }
    }, this.TTL * 60000);
}


public void load() {
    // Load all data here
    this.timestamp = new Date().getTime();
}

public C get(I id) {
    this.verifyCache();
    return this.cache.get(id);
}

public List<C> getAll() {
    this.verifyCache();
    List<C> list = new ArrayList<>(this.cache.values());
    return list;
}

protected abstract C transform(E entity);

protected abstract I getID(E entity);

public abstract String getName();
}
公共抽象类CacheAbstract{
私有长时间戳;
私有类实体类;
私家班;
私有类缓存类;
受保护整数TTL=60;//以分钟为单位。默认为60分钟
私有地图缓存;
私人定时器;
公共CacheAbstract(类entityClass、类idClass、类cacheClass){
this.entityClass=entityClass;
this.idClass=idClass;
this.cacheClass=cacheClass;
}
公共布尔值isExpired(){
返回(this.timestamp+TTL*60000)
这个类不是一个单例,它将由一个工厂实例化,比如说,CacheFactory

public final class CacheFactory {

private Map<String, CacheAbstract> caches;

private CacheFactory() {
}

public void registerCache(CacheAbstract cache) {
    if (caches == null) {
        caches = new HashMap<>();
    }
    if (caches.containsKey(cache.getName())) {
        this.caches.get(cache.getName()).load();
    } else {
        this.caches.put(cache.getName(), cache);
    }
}

public CacheAbstract getCache(String name) throws ExceptionInvalidCacheName {
    if (caches.containsKey(name)) {
        return caches.get(name);
    } else {
        throw new ExceptionInvalidCacheName("KOLOM SERVER [cache]: Cache '" + name + "' not registered");
    }
}

public Boolean isExist(String name) {
    return caches.containsKey(name);
}

public List<String> getNames() {
    return new ArrayList<>(caches.keySet());
}

public static CacheFactory getInstance() {
    return CacheFactoryHolder.INSTANCE;
}

private static class CacheFactoryHolder {

    private static final CacheFactory INSTANCE = new CacheFactory();
}
}
公共最终类缓存工厂{
私有地图缓存;
私有缓存工厂(){
}
公共无效注册表缓存(缓存抽象缓存){
if(缓存==null){
caches=newhashmap();
}
if(caches.containsKey(cache.getName())){
this.caches.get(cache.getName()).load();
}否则{
this.caches.put(cache.getName(),cache);
}
}
公共缓存抽象getCache(字符串名称)抛出ExceptionInvalidCacheName{
if(缓存.容器(名称)){
返回缓存。获取(名称);
}否则{
抛出新的ExceptionInvalidCacheName(“KOLOM服务器[缓存]:缓存“+”名称“+”未注册”);
}
}
公共布尔值isExist(字符串名称){
返回缓存。containsKey(名称);
}
公共列表getNames(){
返回新的ArrayList(caches.keySet());
}
公共静态缓存工厂getInstance(){
返回CacheFactoryHolder.INSTANCE;
}
私有静态类CacheFactoryHolder{
私有静态最终CacheFactory实例=新CacheFactory();
}
}

现在,我如何实现算法,让CacheAbstract在需要时自动刷新?

是的,您只需调用
load()

因为每个匿名类实际上也是一个内部类,所以它有一个对声明它的包含类的引用


但是,只有当您真正想要活动过期时,才会使用计时器。由于每次调用
get()
时都调用了
verifyCache()
,因此您已经有延迟过期。也许这就足够满足您的需要了。

为什么它需要在get方法之外刷新自己?是的,但是有时候get方法不经常被调用,所以我更喜欢将这些值存储在RAM上。谢谢。但是如果get没有被调用,为什么不等到它被调用时再重新加载过期的数据,这样值会更新鲜呢。除非您的持久存储不可靠。
private void onTimer() {
    timer = new Timer();
    timer.schedule(new TimerTask() {

        @Override
        public void run() {
             load(); // Call the containing class method
        }
    }, TTL * 60000);
}