Я использую LoadingCache в своем проекте. Я настроил RemovalListener и CahceLoader для кэша.
LoadingCache<Key, value> cache = cache = (LoadingCache<Key, value>) CacheBuilder
.newBuilder().initialCapacity(50).maximumSize(500).expireAfterAccess(4, HOURS)
.removalListener(new RemovalHander())
.build(new CacheLoader<Key, value>() {
@Override
public Value load(Key request) {
return loadCache(request);
}
});
Я столкнулся с проблемой параллелизма с этим кэшем в следующем сценарии:
- По запросу для Key1, кеш заполняется значением Value *
- Кэш не доступен для Key1 в течение следующих 4 часов
- По истечении 4 часов Key1 помечается как просроченный
- Через 4 часа приходит запрос на доступ к Key1
- По запросу для Key1 (получено в request-thread ) после 4
часов, LoadingCache находит Key1 как просроченный, поэтому он инициирует новый поток (вызов
это cleanup-thread) , чтобы сделать очистку кеша для Key1 и в request-
поток пытается загрузить свежие данные для Key1
- Поскольку обе операции удаления / извлечения выполняются для одного и того же ключа, т.е. ключа 1,
запрос-поток обнаруживает, что запись уже есть, а очистка-поток
удаляет данные.
Итак, вкратце, RemovalHander работает с CacheLoader для Key1.
Я хочу избежать вышеупомянутого случая и подумать о вызове cleanup()
метода LoadingCache
.
Подскажите, пожалуйста, по следующим пунктам:
- Когда должен вызываться метод cleanup ()? Периодически с использованием некоторого SchedulerService или при каждом запросе записи в кеше?
- Есть ли лучший способ решить вышеуказанную проблему?
- Есть ли лучшая замена GuavaCache?