http://www.1point3acres.com/bbs/thread-116171-1-1.html
一直在和他讨论如何实现。。。题目是实现一个hashtable能够对每个entry设置ttl(time to live),ttl一过就删除。一开始感觉有点像LRUCache,就往linkedlist上想了,但是纠结于什么时候check是否要删除entry,后来又想每个entry插入的时候开一个thread,然后ttl后这个thread把对应entry删除,问了有什么优缺点,race condition,如果系统thread没有准时删除怎么办?反正各种跪。
X.
https://gist.github.com/pcan/16faf4e59942678377e0
X. Use ConcurrentHashMap and a thread
http://www.java2s.com/Code/Java/Collections-Data-Structure/ExpiringMap.htm
==> we can also remove (one or all) outdated element when size > threshold.
https://git.eclipse.org/r/#/c/41522/1/org.eclipse.scout.commons/src/org/eclipse/scout/commons/TTLCache.java
http://nirlevy.blogspot.com/2007/11/java-ttl-cache-quick-and-dirty-way.html
===> not good implementation.
http://www.javaworld.com/article/2071825/build-ci-sdlc/the-timestamp-based-caching-framework--current-data-with-peak-performance.html
一直在和他讨论如何实现。。。题目是实现一个hashtable能够对每个entry设置ttl(time to live),ttl一过就删除。一开始感觉有点像LRUCache,就往linkedlist上想了,但是纠结于什么时候check是否要删除entry,后来又想每个entry插入的时候开一个thread,然后ttl后这个thread把对应entry删除,问了有什么优缺点,race condition,如果系统thread没有准时删除怎么办?反正各种跪。
X.
https://gist.github.com/pcan/16faf4e59942678377e0
private final DelayQueue<ExpiringKey> delayQueue = new DelayQueue<ExpiringKey>();
public SelfExpiringHashMap(final long defaultMaxLifeTimeMillis) {
internalMap = new ConcurrentHashMap<K, V>();
expiringKeys = new WeakHashMap<K, ExpiringKey<K>>();
this.maxLifeTimeMillis = defaultMaxLifeTimeMillis;
}
public V put(final K key, final V value, final long lifeTimeMillis) {
cleanup();
final ExpiringKey delayedKey = new ExpiringKey(key, lifeTimeMillis);
expireKey(expiringKeys.put(key, delayedKey));
delayQueue.offer(delayedKey);
return internalMap.put(key, value);
}
X. Use ConcurrentHashMap and a thread
http://www.java2s.com/Code/Java/Collections-Data-Structure/ExpiringMap.htm
private final ConcurrentHashMap<K, ExpiringObject> delegate;
private final CopyOnWriteArrayList<ExpirationListener<V>> expirationListeners;
private final Expirer expirer;
private ExpiringMap(final ConcurrentHashMap<K, ExpiringObject> delegate, final CopyOnWriteArrayList<ExpirationListener<V>> expirationListeners, final int timeToLive, final int expirationInterval) {
this.delegate = delegate;
this.expirationListeners = expirationListeners;
this.expirer = new Expirer();
expirer.setTimeToLive(timeToLive);
expirer.setExpirationInterval(expirationInterval);
}
public V put(final K key, final V value) {
final ExpiringObject answer = delegate.put(key, new ExpiringObject(key, value, System.currentTimeMillis()));
if (answer == null) {
return null;
}
return answer.getValue();
}
public V get(final Object key) {
final ExpiringObject object = delegate.get(key);
if (object != null) {
object.setLastAccessTime(System.currentTimeMillis());
return object.getValue();
}
return null;
}
private void processExpires() {
final long timeNow = System.currentTimeMillis();
for (final ExpiringObject o : delegate.values()) {
if (timeToLiveMillis <= 0) {
continue;
}
final long timeIdle = timeNow - o.getLastAccessTime();
if (timeIdle >= timeToLiveMillis) {
delegate.remove(o.getKey());
for (final ExpirationListener<V> listener : expirationListeners) {
listener.expired(o.getValue());
}
}
}
}
X. Improve outdated element when get or iterate element.==> we can also remove (one or all) outdated element when size > threshold.
https://git.eclipse.org/r/#/c/41522/1/org.eclipse.scout.commons/src/org/eclipse/scout/commons/TTLCache.java
http://nirlevy.blogspot.com/2007/11/java-ttl-cache-quick-and-dirty-way.html
===> not good implementation.
http://www.javaworld.com/article/2071825/build-ci-sdlc/the-timestamp-based-caching-framework--current-data-with-peak-performance.html
Cache<Key, Graph> graphs = CacheBuilder.newBuilder()
.concurrencyLevel(4)
.weakKeys()
.maximumSize(10000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(
new CacheLoader<Key, Graph>() {
public Graph load(Key key) throws AnyException {
return createExpensiveGraph(key);
}
});