Google guava cachebuilder использует большее время между expipreAfterAccess и expireActerWrite

Во-первых, я извиняюсь, если я не придерживался каких-либо правил и положений stackoverflow, поскольку я впервые задаю вопрос.

Я нахожусь в ситуации, когда мне нужно использовать карту с истекающим сроком действия, где элементы с карты могут быть автоматически удалены через определенное время. Я рад, что могу использовать cachebuilder из google guava. Мне нужно указать лимит времени по умолчанию, который я могу сделать с помощью expireAfterWrite(..), но мне нужно переопределить его после моего доступа. Я могу использовать expipreAfterAccess(..), но он все равно удаляет его после начального времени, установленного expipreAfterWrite(..)

Как я могу добиться этой функциональности, чтобы критерии удаления проверяли большее время между expipreAfterAccess и expireActerWrite

Спасибо, что заглянули в это


person Ricky M    schedule 13.04.2015    source источник
comment
Что произойдет, если вы не установите expireAfterWrite? Разве это не достигает именно того, что вы хотите?   -  person Guillaume Polet    schedule 14.04.2015
comment
Они должны быть удалены через определенный период времени, если пользователь не получил к ним доступ.   -  person Ricky M    schedule 14.04.2015
comment
@RickyM: Да, и они будут, потому что запись — это еще и доступ.   -  person Louis Wasserman    schedule 14.04.2015
comment
Непонятно, что вы хотите сделать. Как изначально заполняется карта? Как предполагает префикс Loading, если записи нет, она будет создана для вас (с использованием CacheLoader).   -  person fge    schedule 14.04.2015


Ответы (1)


Я бы просто посоветовал не устанавливать значение expireAfterWrite. Это позволит достичь именно того, что вы хотите.

См. небольшой пример ниже.

  1. Сначала он иллюстрирует вашу текущую ситуацию (expireAfterWrite=1 секунда, expireAfterAccess=2 секунды) --> Каждую секунду значение перезагружается
  2. Затем он создает кеш только (expireAfterAccess = 2 секунды) и обращается к нему каждые 100 мс -> значение загружается только один раз
  3. Затем он спит в течение 2 секунд -> значение правильно перезагружается.

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import com.google.common.base.Stopwatch;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

public class TestCache {

    private static final String KEY = "Key";

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CacheLoader<String, String> loader = new CacheLoader<String, String>() {
            @Override
            public String load(String key) throws Exception {
                System.out.println("Loading key");
                return key;
            }
        };
        LoadingCache<String, String> cache1 = CacheBuilder.newBuilder().expireAfterAccess(2L, TimeUnit.SECONDS)
                .expireAfterWrite(1L, TimeUnit.SECONDS).build(loader);
        cache1.get(KEY); // First write
        testCache(cache1);
        LoadingCache<String, String> cache2 = CacheBuilder.newBuilder().expireAfterAccess(2L, TimeUnit.SECONDS).build(loader);
        testCache(cache2);
        System.out.println("Final test on cache 2");
        Thread.sleep(2001);
        System.out.println(cache2.get(KEY));

    }

    private static void testCache(LoadingCache<String, String> cache1) throws ExecutionException, InterruptedException {
        Stopwatch sw = Stopwatch.createStarted();
        while (sw.elapsed(TimeUnit.SECONDS) < 5) {
            System.out.println(sw.elapsed(TimeUnit.MILLISECONDS) + " " + cache1.get(KEY));
            Thread.sleep(100);
        }
    }
}
person Guillaume Polet    schedule 13.04.2015