2018-08-29
請參考下列文章
expireAfterAccess
block
所有存取該 cache key 的 threadexpireAfterWrite
block
所有存取該 cache key 的所有 thread上次取存的時間點
為基準來記算何時會 expire,也就是說只要一直被存取就不會 expirerefreshAfterWrite
注意!是再次訪問,也就是未訪問前可能都不會更新。
不會 block
所有存取該 cache key 的 threadrefreshAfterWrite requires a LoadingCache
exception同步(sync)
去獲取返回新值。新值未取回前,所有要取新值 的 thread 都會被 block。直到下次訪問
才以 非同步(async)
方式 refresh cache。在 refresh cache 動作完成前,大多數針對該 cache key 的請求 thread 會立刻返回舊值,不會被 block二者一起使用時的行為請參考下列文章
深入Guava Cache的refresh和expire刷新機制
重點是這一段
可以看出refreshAfterWrite和expireAfterWrite兩種方式各有優缺點,各有使用場景。那麼能否在refreshAfterWrite和expireAfterWrite找到一個折中?比如說控制緩存每1s進行refresh,如果超過2s沒有訪問,那麼則讓緩存失效,下次訪問時不會得到舊值,而是必須得待新值加載。由於guava官方文檔沒有給出一個詳細的解釋,查閱一些網上資料也沒有得到答案,因此只能對源碼進行分析,尋找答案。經過分析,當同時使用兩者的時候,可以達到預想的效果,這真是一個好消息吶!
重點是這一段,不過我沒有很懂它表達的意思
In contrast to expireAfterWrite, refreshAfterWrite will make a key eligible for refresh after the specified duration, but a refresh will only be actually initiated when the entry is queried. (If CacheLoader.reload is implemented to be asynchronous, then the query will not be slowed down by the refresh.) So, for example, you can specify both refreshAfterWrite and expireAfterWrite on the same cache, so that the expiration timer on an entry isn't blindly reset whenever an entry becomes eligible for a refresh, so if an entry isn't queried after it comes eligible for refreshing, it is allowed to expire.