Как настроить кеш гуавы для удаления элемента после чтения?
Я хотел бы удалить (сделать недействительным) элемент после его чтения из кэша.
Таким образом, элемент должен присутствовать в кэше до первого чтения.
Я пытался добавить expireAfterAccess(0, TimeUnit.NANOSECONDS)
но тогда кеш не заполняется.
Есть ли способ использовать кеш Guava таким образом, или мне нужно сделать недействительным элемент вручную после чтения?
3 ответа
Это не сработает. "Доступ" означает "доступ для чтения или записи", и когда он истекает сразу после чтения, то он также истекает сразу после записи.
Вы можете удалить запись вручную. Вы можете использовать asMap()
просмотреть для того, чтобы сделать это в единый доступ:
String getAndClear(String key) {
String[] result = {null};
cache.asMap().compute(key, (k, v) ->
result[0] = v;
return null;
});
return result[0];
}
Вы можете переключиться на Caffeine, который является более продвинутым кешем Guava и предлагает очень гибкий expireAfter(Expiry)
,
Однако я не думаю, что вам нужна работа для кеша. Поскольку одноразовые номера никогда не должны повторяться, я не могу представить себе причины хранить их. Обычно вы генерируете и используете их немедленно.
Возможно, вы делаете это неправильно, и вы можете захотеть уточнить, чтобы избежать возможных проблем с безопасностью.
В моем примере одноразовые номера создаются дважды:
LoadingCache<String, String> cache = CacheBuilder.newBuilder().expireAfterAccess(0, TimeUnit.NANOSECONDS)
.build(new CacheLoader<String, String>() {
@Override
public String load(String key) throws Exception {
return createNonce();
}
});
@Test
public void test_cache_eviction() throws Exception {
String nonce1 = cache.getUnchecked("key");
String nonce2 = cache.getUnchecked("key");
}
public String createNonce() {
String createdNonce = "createdNonce";
System.out.println(createdNonce);
return createdNonce;
}
В логах "creatNonce" печатаются дважды.
Операция "получить и удалить" является простой remove
на интерфейсе карты:
Object cachedValue = cache.asMap().remove(key);