Потокобезопасный кеш одного объекта в Java - PullRequest
37 голосов
/ 03 сентября 2010

допустим, у нас есть объект CountryList в нашем приложении, который должен возвращать список стран. Загрузка стран является тяжелой операцией, поэтому список следует кэшировать.

Дополнительные требования:

  • CountryList должен быть потокобезопасным
  • CountryList должен загружаться ленивым (только по требованию)
  • CountryList должен поддерживать аннулирование кэша
  • CountryList должен быть оптимизирован с учетом того, что кэш будет очень редко аннулирован

Я придумал следующее решение:

public class CountryList {
    private static final Object ONE = new Integer(1);

    // MapMaker is from Google Collections Library    
    private Map<Object, List<String>> cache = new MapMaker()
        .initialCapacity(1)
        .makeComputingMap(
            new Function<Object, List<String>>() {
                @Override
                public List<String> apply(Object from) {
                    return loadCountryList();
                }
            });

    private List<String> loadCountryList() {
        // HEAVY OPERATION TO LOAD DATA
    }

    public List<String> list() {
        return cache.get(ONE);
    }

    public void invalidateCache() {
        cache.remove(ONE);
    }
}

Что вы думаете об этом? Вы видите что-то плохое в этом? Есть ли другой способ сделать это? Как я могу сделать это лучше? Стоит ли искать в этом случае совершенно другое решение?

Спасибо.

Ответы [ 11 ]

0 голосов
/ 03 сентября 2010

Это выглядит нормально для меня (я полагаю, MapMaker из коллекций Google?) В идеале вам не нужно было бы использовать Map, потому что у вас нет ключей, но реализация скрыта от любых вызывающих программ, которых я не вижуэто как большое дело.

...