我们有一个简单但非常常用的缓存,由ConcurrentHashMap实现。现在,我们希望定期刷新所有值(例如,每15分钟一次)。
我想要这样的代码:
private void regularCacheCleanup() {
final long now = System.currentTimeMillis();
final long delta = now - cacheCleanupLastTime;
if (delta < 0 || delta > 15 * 60 * 1000) {
cacheCleanupLastTime = now;
clearCache();
}
}但应包括:
现在,我想在ThreadLocal中实现一个短计时器。当它过期时,将以同步的方式检查真正的计时器。然而,这是一个非常多的代码,所以一个更简单的想法会更好。
发布于 2012-09-14 12:10:38
解决这个问题的主流方法是使用一些计时器线程在指定的时间间隔内刷新缓存。但是,由于您不需要创建新线程,我可以想到的一个可能的实现是伪时间缓存刷新。基本上,我会在缓存访问器(put和get方法)中插入检查,每次客户端使用这些方法时,我都会在执行put或get操作之前检查缓存是否需要刷新。这是一个粗略的想法:
class YourCache {
// holds the last time the cache has been refreshed in millis
private volatile long lastRefreshDate;
// indicates that cache is currently refreshing entries
private volatile boolean cacheCurrentlyRefreshing;
private Map cache = // Your concurrent map cache...
public void put(Object key, Object element) {
if (cacheNeedsRefresh()) {
refresh();
}
map.put(key, element);
}
public Object get(Object key) {
if (cacheNeedsRefresh()) {
refresh();
}
return map.get(key);
}
private boolean cacheNeedsRefresh() {
// make sure that cache is not currently being refreshed by some
// other thread.
if (cacheCurrentlyRefreshing) {
return false;
}
return (now - lastRefreshDate) >= REFRESH_INTERVAL;
}
private void refresh() {
// make sure the cache did not start refreshing between cacheNeedsRefresh()
// and refresh() by some other thread.
if (cacheCurrentlyRefreshing) {
return;
}
// signal to other threads that cache is currently being refreshed.
cacheCurrentlyRefreshing = true;
try {
// refresh your cache contents here
} finally {
// set the lastRefreshDate and signal that cache has finished
// refreshing to other threads.
lastRefreshDate = System.currentTimeMillis();
cahceCurrentlyRefreshing = false;
}
}
}就我个人而言,我不会考虑这样做,但是如果您不想或者不能创建计时器线程,那么这可能是您的一个选择。
请注意,虽然此实现避免了锁,但由于竞赛事件,它仍然容易出现重复刷新。如果这对您的需求是可以的,那么它应该没有问题。但是,如果您有更严格的要求,那么您需要设置锁定,以便正确地同步线程并避免竞争事件。
https://stackoverflow.com/questions/12423502
复制相似问题