本地缓存需要注意的点是如何和垃圾回收机制不冲突,如何避免失效对象进入old区。
防止full gc。考虑采用弱引用
http://shangjava.iteye.com/blog/1144189
http://www.codeinstructions.com/2008/09/weakhashmap-is-not-cache-understanding.html
其实偶尔的full gc对应用性能影响不大,特别是采用了可以和用户线程并行的GC。
1
本地缓存方案,适用于高并发下的缓存读取。
使用hashmap作为缓存器
缓存对象:createTime,value,lifeTime,isInvalid (改进方案可以采用原子int,表示一个缓存对象允许的失效次数,避免大量失效对系统造成压力)
getValue
当系统当前时间-createTime小于lifeTime时,直接返回value。
当系统当前时间-createTime大于lifeTime时,if(isInvalid) return value ;else isInvalid=true,return null.
基于LikedHashMap实现非线程安全的LRUHashMap
class LRUHashMap extends LinkedHashMap<String, Object> { private int MAX_ENTRIES; public LRUHashMap(int size) { MAX_ENTRIES = size; } protected boolean removeEldestEntry(Map.Entry<String, Object> eldest) { return size() > MAX_ENTRIES; } }
public class CacheObject { long createTime; long lifeTime; Object value; AtomicInteger invalidTimes; public CacheObject(long lifeTime, Object value) { this.lifeTime = lifeTime; this.value = value; invalidTimes = new AtomicInteger(0); this.createTime = System.currentTimeMillis(); } public long getCreateTime() { return createTime; } public void setCreateTime(long createTime) { this.createTime = createTime; } public long getLifeTime() { return lifeTime; } public void setLifeTime(long lifeTime) { this.lifeTime = lifeTime; } public Object getValue() { if (System.currentTimeMillis() - createTime > lifeTime) { if (invalidTimes.incrementAndGet() > 3) { return value; } else { return null; } } return value; } public void setValue(Object value) { this.value = value; } public AtomicInteger getInvalidTimes() { return invalidTimes; } public void setInvalidTimes(AtomicInteger invalidTimes) { this.invalidTimes = invalidTimes; } }
public class LocalCache { LRUHashMap<String, CacheObject> cacheArea = new LRUHashMap(10); public Object get(String key) { CacheObject cacheObject = cacheArea.get(key); return cacheObject == null ? null : cacheObject.getValue(); } public void put(String key, Object value, long lifeTime) { CacheObject cacheObject = new CacheObject(lifeTime, value); cacheArea.put(key, cacheObject); } }
2
Memcached Cache现在已经被大家广泛使用,但是千万不要认为对Cache的操作是低损耗的,要知道这类集中式Cache对Socket连接数(会牵涉到linux操作系统文件句柄可用数),带宽,网络IO都是有要求的,有要求就意味着会有损失,因此积少成多,集腋成裘。
所以说本地缓存是很有价值的,memcache也鼓励使用本地缓存,对于一致性不敏感的数据
牛叉叉的放翁
http://blog.csdn.net/cenwenchu79/article/details/4134746
http://www.infoq.com/cn/articles/memcached-java
需要了解一致性hash