#java #guava
#java #гуава
Вопрос:
У меня есть кэш 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
метод, который принимает функцию загрузчика get(K key, Callable<? extends V> loader)
, чтобы избежать возможности того, что два потока одновременно вызывают 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
}
Комментарии:
1. Взгляните на
build
перегрузку метода, которая принимаетCacheLoader
.
Ответ №1:
Создайте LoadingCache
вместо Cache
с CacheLoader
, чтобы достичь того, чего вы хотите. Пожалуйста, обратитесь к вики-странице Guava CachesExplained, в частности:
LoadingCache — это
Cache
встроенный с подключеннымCacheLoader
. (…) Канонический способ запроса aLoadingCache
— это методget(K)
. Это либо вернет уже кэшированное значение, либо будет использовать кэшCacheLoader
для атомной загрузки нового значения в кэш.
В вашем случае:
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");