解决此问题的主流方法是使用一些计时器线程以指定的时间间隔刷新缓存。但是,由于您不需要创建新线程,我能想到的一种可能的实现是伪定时缓存刷新。基本上,我会在缓存访问器(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;
}
}
}
我个人不会考虑这样做,但如果你不想或不能创建计时器线程,那么这可能是你的一个选择。
Note that although this implementation avoids locks, it is still prone to duplicate refreshes due to race events. If this is ok for your requirements then it should be no problem. If however you have stricter requirements then you need to put locking in order to properly synchronise the threads and avoid race events.