使用带有 <String, Boolean> 的加载缓存的正确用法?

Correct usage for using loading cache with a <String, Boolean>?

我有一个字符串、布尔值的缓存。:

Cache<String, Boolean> myCache = CacheBuilder.newBuilder().build();

我的使用模式是:

if (myCache.get("some-key") == null)  {
     // "some-key" not in cache, do stuff, then insert it
     myCache.put("some-key", Boolean.TRUE);
} 
else {
    // "some-key" already in cache
}

我正在尝试更改此设置,以便它使用采用加载程序函数 get(K key, Callable<? extends V> loader) 的替代 get 方法,以避免两个线程都调用 myCache.get("some-key") == null 并且两者都调用的可能性输入 if 块。

我不确定下面的方法是否正确?

我认为myCache.get("some-key", myCacheLoader)如果不存在就会将some-key插入到缓存中,但我还需要知道它是否存在,所以我不认为下面的代码是正确的。

CacheLoader<String, Boolean> myCacheLoader = createMyCacheLoader();
Cache<String, Boolean> myCache = CacheBuilder.newBuilder().build();

private static CacheLoader<String, Boolean> createMyCacheLoader(){
    return new CacheLoader<String, Boolean>(){
        @Override
        public Boolean load(final String key){
            return Boolean.TRUE;
        }
    };
}

if (!myCache.get("some-key", myCacheLoader))  { // I don't think this can ever be false?
    // I don't think if block will ever be entered?
    // How can I find out if an item isn't in the cache when using a loading cache?
} 
else {
    // "some-key" already in cache 
}

建立LoadingCache instead of Cache with the CacheLoader to achieve what you want. Please refer to Guava CachesExplained wiki page,具体来说:

A LoadingCache is a Cache built with an attached CacheLoader. (...) The canonical way to query a LoadingCache is with the method get(K). This will either return an already cached value, or else use the cache's CacheLoader to atomically load a new value into the cache.

你的情况:

    CacheLoader<String, Boolean> myCacheLoader = CacheLoader.from(key -> Boolean.TRUE);
    LoadingCache<String, Boolean> myCache = CacheBuilder.newBuilder()
            // optional config for LoadingCache
            .build(myCacheLoader);

    // or even inlined:
    LoadingCache<String, Boolean> myCache = CacheBuilder.newBuilder()
            // optional config for LoadingCache
            .build(CacheLoader.from(key -> Boolean.TRUE));

    try {
        final Boolean isValuePresent = myCache.get("some-key");
    } catch (ExecutionException e) {
        throw new UncheckedExecutionException(e.getCause()); // or whatever
    }

    final Boolean isAnotherValuePresent = myCache.getUnchecked("some-key-as-well");