cachingguavagoogle-guava-cache

Does Google Guava Cache do deduplication when refreshing value of the same key


I implemented a non-blocking cache using Google Guava, there's only one key in the cache, and value for the key is only refreshed asynchronously (by overriding reload()).

My question is that does Guava cache handle de-duplication if the first reload() task hasn't finished, and a new get() request comes in.

    //Cache is defined like below
    this.cache = CacheBuilder
            .newBuilder()
            .maximumSize(1)
            .refreshAfterWrite(10, TimeUnit.MINUTES)
            .recordStats()
            .build(loader);

//reload is overwritten asynchronously
@Override
public ListenableFuture<Map<String, CertificateInfo>> reload(final String key, Map<String, CertificateInfo> prevMap) throws IOException {
    LOGGER.info("Refreshing certificate cache.");
    ListenableFutureTask<Map<String, CertificateInfo>> task = ListenableFutureTask.create(new Callable<Map<String, CertificateInfo>>() {
        @Override
        public Map<String, CertificateInfo> call() throws Exception {
            return actuallyLoad();
        }
    });
    executor.execute(task);
    return task;
}

Solution

  • Yes, see the documentation for LoadingCache.get(K) (and it sibling, Cache.get(K, Runnable)):

    If another call to get(K) or getUnchecked(K) is currently loading the value for key, simply waits for that thread to finish and returns its loaded value.

    So if a cache entry is currently being computed (or reloaded/recomputed), other threads that try to retrieve that entry will simply wait for the computation to finish - they will not kick off their own redundant refresh.