Вы можете использовать гуаву для этой цели. Обратите внимание на предостережение об очистке, как отмечено в документации здесь (воспроизведено ниже).
Кэши, созданные с помощью CacheBuilder, не выполняют очистку и высвобождают значения «автоматически» или сразу послезначение истекает, или что-нибудь в этом роде. Вместо этого он выполняет небольшие объемы обслуживания во время операций записи или периодических операций чтения, если записи выполняются редко.
Причина этого заключается в следующем: если мы хотим непрерывно выполнять обслуживание кэша, нам необходимо создатьпоток, и его операции будут конкурировать с пользовательскими операциями для общих блокировок. Кроме того, некоторые среды ограничивают создание потоков, что делает CacheBuilder непригодным для использования в этой среде.
Вместо этого мы предоставляем выбор в ваши руки. Если ваш кеш высокопроизводительный, вам не нужно беспокоиться о выполнении обслуживания кеша для очистки записей с истекшим сроком действия и тому подобного. Если ваш кэш выполняет запись только изредка, и вы не хотите, чтобы очистка блокировала чтение из кэша, вы можете создать собственный поток обслуживания, который будет вызывать Cache.cleanUp () через регулярные интервалы.
Если вы хотите запланироватьрегулярное обслуживание кеша для кеша, в котором редко есть записи, просто запланируйте обслуживание с помощью ScheduledExecutorService.
Что касается контрольной точки размера, вы правы, что size()
является приблизительным. Если вам нужно выполнить какое-либо действие, когда запись недействительна, вы должны использовать функцию removalListener
. Соответствующий пример кода из документации , воспроизведенной сейчас.
CacheLoader<Key, DatabaseConnection> loader = new CacheLoader<Key, DatabaseConnection> () {
public DatabaseConnection load(Key key) throws Exception {
return openConnection(key);
}
};
RemovalListener<Key, DatabaseConnection> removalListener = new RemovalListener<Key, DatabaseConnection>() {
public void onRemoval(RemovalNotification<Key, DatabaseConnection> removal) {
DatabaseConnection conn = removal.getValue();
conn.close(); // tear down properly
}
};
return CacheBuilder.newBuilder()
.expireAfterWrite(2, TimeUnit.MINUTES)
.removalListener(removalListener)
.build(loader);