因为我有一个批量操作来获取数据,所以我不想使用 refresh() 来更新单个项目,我想利用批量调用来定期更新缓存。
我想到了一些方法,因为我一直在调用 get() 来缓存,我想知道哪种方法是最佳的。
方法 1 定期调用 getAll(),它调用 loadAll()
LoadingCache<String, String> cache = CacheBuilder.newBuilder()
.ticker(ticker)
.refreshAfterWrite(5, TimeUnit.Minut)
.expireAfterAccess(30, TimeUnit.MINUTES)
.build(cacheLoader);
private static final class CacheLoader extends CacheLoader<String, String> {
@Override
public String load(final String key) {
return db.getItem(key);
}
@Override
public ListenableFuture<String> reload(String key) {
ListenableFutureTask<String> task = ListenableFutureTask.create(new Callable<String>() {
public String call() {
return db.getItem(key);
}
});
executor.execute(task);
return task;
}
@Override
public String loadAll(final List<String> key) {
return db.bulkGetItems(keyList);
}
}
private class RefresherRunnable implements Runnable {
private volatile boolean stopped = false;
@Override
public void run() {
while (!stopped) {
try {
List<String> keys = getKeys();
cache.getAll(keys);
} catch (Exception e) {
//log
}
final long nextSleepInterval = 1000 * 60;
try {
Thread.sleep(nextSleepInterval);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
方法二
只需使用Cache.asMap().putAll
private class RefresherRunnable implements Runnable {
private volatile boolean stopped = false;
@Override
public void run() {
while (!stopped) {
try {
List<String> keys = getKeys();
Map<String, String> keyValueMap = db.bulkGetItems(keys);
cache.asMap().putAll(keyValueMap);
} catch (Exception e) {
//log
}
final long nextSleepInterval = 1000 * 60;
try {
Thread.sleep(nextSleepInterval);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
我从https://github.com/google/guava/wiki/CachesExplained#inserted-directly读到过, 听起来 getAll 比 asMap.put() 好,所以我猜是首选方法 1?