我得到的結果,我真的不明白,當使用番石榴緩存。番石榴緩存refreshAfterWrite混淆
我正在實現一個我想異步刷新的密鑰緩存。
我每秒都會打開緩存,並且我已經將refreshAfterWrite設置爲20秒。 我的加載/重新加載功能需要5秒鐘。
如果我打印出在負載/重裝方法開始時的當前時間 - 我希望一些結果是這樣的:
負載通話開始於00:00:00
重裝通話開始於0點00分25秒
重載呼叫開始在零時00分五十秒
所以負載將需要5秒之後(5 + 20 = 25)的下一個寫入將觸發20秒。這寫將發生在50秒後(25 + 5 + 20 = 50)秒。等等
相反,我得到:
負載通話開始於00:00:00
重裝通話開始在00:00:25
重裝通話開始於00:00:30
這表明,發生第二次重裝後直奔第一重裝完成處理。
我認爲在將來處理完之後會發生寫入操作,因此下一次重新加載會在此之後計劃20秒?
我發現了一個錯誤,或者我對refreshAfterWrite的工作原理有一個基本的誤解?
示例代碼如下:
private static SimpleDateFormat format = new SimpleDateFormat("hh:mm:ss");
public static void main(String[] args) throws ExecutionException, InterruptedException {
final ExecutorService executor = Executors.newFixedThreadPool(3);
final LoadingCache<String, Long> cache = CacheBuilder.newBuilder().maximumSize(1) //
.refreshAfterWrite(20, TimeUnit.SECONDS)//
.build(new CacheLoader<String, Long>() {//
public Long load(String key) {
return getLongRunningProcess("load", key);
}
public ListenableFuture<Long> reload(final String key, Long prevGraph) {
ListenableFutureTask<Long> task = ListenableFutureTask.create(new Callable<Long>() {
public Long call() {
return getLongRunningProcess("reload", key);
}
});
executor.execute(task);
return task;
}
});
while (true) {
Thread.sleep(1000L);
cache.get(CACHE_KEY);
}
}
private static Long getLongRunningProcess(String callType, String key) {
System.out.printf("%s call started at %s\n", callType, format.format(new Date()));
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
return counter.getAndIncrement();
}
}
幾個星期前,我一直在尋找一個遺忘的單個元素的緩存功能。可悲的是,番石榴不支持這一點,所以我自己寫了一個。看看我在http://codereview.stackexchange.com/questions/18056/ability-to-forget-the-memoized-supplier-value上這樣做的嘗試,如果需要的話可以隨意使用此代碼。 – mindas