我想创建一个带有工厂的缓存对象,用于多个表。 每个缓存都有自己的生命周期,这些生命周期彼此不同。 例如,City对象的生命周期约为一年,设施列表对象的生命周期约为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(); }这个类不是单例,而是由工厂实例化的,比方说,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(); } }现在,我如何实现算法让CacheAbstract在需要时刷新自己?
I would like create a cache object with a factory, for a multiple tables. Each cache has their own life time which are different to one another. For example, lifetime for City object is about a year, and lifetime for facility list object is about 1 day.
This below is my cache class
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(); }this class is not a singleton, and will be instantiated by a factory., let's say, 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(); } }Now, how I can implement algorithm to let CacheAbstract to refresh itself when needed?
最满意答案
是的,你可以简单地调用load() :
private void onTimer() { timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { load(); // Call the containing class method } }, TTL * 60000); }因为每个匿名类实际上也是一个内部类,所以它引用了声明它的包含类。
但是,如果你真的想要主动过期,你只会使用一个Timer。 由于在每次调用get()都调用了verifyCache() ,因此您已经有了延迟到期。 也许这足以满足您的需求。
Yes, you can simply call load():
private void onTimer() { timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { load(); // Call the containing class method } }, TTL * 60000); }because every anonymous class is actually also an inner class, so it has a reference to the containing class that declares it.
But, you would only use a Timer if you really wanted active expiration. You already have lazy expiration due to the call to verifyCache() in every call to get(). Maybe that's enough for your needs now.
更多推荐
发布评论