1. Введение
В этой статье давайте посмотрим на кофеин - высокоэффективную библиотеку Java Cache.
Одно фундаментальное различие между кешем и картой заключается в том, что кэши могут перерабатывать хранимые элементы.
Политика утилизации заключается в удалении объектов в указанное время. Эта стратегия напрямую влияет на скорость попадания в кеш - важная особенность библиотеки кэша.
Кофеин обеспечивает почти оптимальную скорость попадания из-за его использования стратегии утилизации Tinylfu.
2. Зависимость
Нам нужно добавить зависимость от кофеина в pom.xml:
<Depective> <groupid> com.github.ben-manes.caffeine </GroupId> <straCactId> Caffeine </artifactid> <sersive> 2.5.5 </version> </depertion>
Вы можете найти последнюю версию кофеина на Maven Central.
3. Заполните кеш
Давайте посмотрим на стратегии заполнения трех кеша кофеина: ручная, синхронная нагрузка и асинхронная нагрузка.
Во -первых, мы пишем класс для хранения типа значения в кэше:
Класс DataObject {Private Final String Data; Частный статический int objectcounter = 0; // Стандартные конструкторы/getters public static dataObject get (String Data) {ObjectCounter ++; вернуть новый DataObject (data); }}3.1. Ручная начинка
В этой стратегии мы вручную вставляем ценность в кеш, прежде чем получить его.
Давайте инициализируем кеш:
Cache <String, dataObject> cache = caffeine.newbuilder () .expireafterwrite (1, timeUnit.minutes) .maximumSize (100) .build ();
Теперь мы можем использовать метод Getifresent, чтобы получить некоторые значения из кэша. Если это значение не существует в кэше, этот метод возвращает NULL:
String key = "a"; dataObject dataoBject = cache.getifpresent (key); Assertnull (DataObject);
Мы можем использовать метод POT, чтобы вручную заполнить кеш:
cache.put (key, dataobject); dataobject = cache.getifpresent (key); AssertNotnull (DataObject);
Мы также можем использовать метод получения значения, который передает функцию с ключом параметра в качестве параметра. Если ключа не существует в кэше, функция будет использоваться для обеспечения резервного значения, которое вставлено в кэш после расчета:
dataObject = cache .get (key, k -> dataObject.get ("Данные для")); AssertNotnull (DataObject); assertequals («данные для A», dataobject.getData ());Метод получения может выполнять расчеты атомно. Это означает, что вы делаете расчет только один раз - даже если несколько потоков запрашивают значение одновременно. Вот почему использование GET лучше, чем Getifresent.
Иногда нам нужно вручную закончить некоторые кэшированные значения:
cache.invalidate (key); dataobject = cache.getifpresent (key); Assertnull (DataObject);
3.2. Синхронная нагрузка
Этот метод загрузки кэша использует метод GET с ручной стратегией, аналогичной функции, используемой для инициализации значений. Посмотрим, как его использовать.
Во -первых, нам нужно инициализировать кэш:
Загрузка Cache <String, dataObject> cache = caffeine.newbuilder () .maximumsize (100).
Теперь мы можем использовать метод получить значение для получения значения:
DataObject DataObject = cache.get (key); AssertNotnull (DataObject); assertequals («данные для» + key, dataobject.getData ());
Мы также можем использовать метод Getall, чтобы получить набор значений:
Map <string, dataObject> dataObjectmap = cache.getall (arrays.aslist ("a", "b", "c")); assertequals (3, dataobjectmap.size ());Получить значения из базовой функции инициализации бэкэнд, переданной методу сборки. Это позволяет использовать кэш в качестве основного фасада доступа к значениям.
3.3. Асинхронная загрузка
Эта политика делает то же самое, что и раньше, но выполняет операцию асинхронно и возвращает завершаемое место, содержащее значение:
AsyncloadingCache <string, dataObject> cache = caffeine.newbuilder () .maximumsize (100).
Мы можем использовать методы Get and Getall таким же образом, принимая во внимание, что они возвращают завершаемое количество:
String key = "a"; cache.get (key) .thenaccept (dataobject -> {assertnotnull (dataobject); cache.getall (arrays.aslist ("a", "b", "c"))) .thenaccept (dataobjectmap -> assertequals (3, dataobjectmap.size ()));CompleteFuture имеет много полезных API, и вы можете получить больше в этой статье.
4. value Recovery
Кофеин имеет три стратегии восстановления стоимости: на основе размеров, на основе времени и на основе эталон.
4.1. Переработка на основе размера
Этот метод переработки предполагает, что переработка происходит, когда превышается ограниченный размер кэша. Есть два способа получить размер: подсчитать объект в кеше или получить вес.
Давайте посмотрим, как рассчитать объекты в кэше. Когда кэш инициализируется, его размер равен нулю:
Загрузка cache <string, dataObject> cache = caffeine.newbuilder () .maximumsize (1) .build (k -> dataobject.get («Данные для» + k)); assertequals (0, cache.estimatedsize ());
Когда мы добавляем значение, размер значительно увеличивается:
cache.get ("a"); assertequals (1, cache.estimatedsize ());Мы можем добавить второе значение в кэш, что приводит к удалению первого значения:
cache.get ("b"); cache.cleanup (); assertequals (1, cache.estimatedsize ());Стоит отметить, что перед тем, как получить размер кэша, мы называем метод очистки. Это связано с тем, что переработка кэша выполняется асинхронно, и этот подход помогает ждать завершения переработки.
Мы также можем пройти функцию взвешителя, чтобы получить размер кэша:
Загрузка Cache <String, dataObject> cache = caffeine.newbuilder () .maximumweight (10) .weeler ((k, v) -> 5) .build (k -> dataObject.get ("Данные для" + k)); assertequals (0, cache.estimatedsize ()); cache.get ("a"); assertequals (1, cache.estimatedsize ()); cache.get ("b"); assertequals (2, cache.estimatedsize ());Когда вес превышает 10, значение удаляется из кэша:
cache.get ("c"); cache.cleanup (); assertequals (2, cache.estimatedsize ());4.2. На основании восстановления времени
Эта стратегия утилизации основана на времени истечения срока действия, и есть три типа:
Давайте настроим политику истечения срока действия после доступа, используя метод истечения срока действия:
Загрузка cache <string, dataObject> cache = caffeine.newbuilder () .expireafteraccess (5, timeUnit.minutes) .build (k -> dataObject.get («Данные для» + k));
Чтобы настроить политику истечения срока действия после записи, мы используем метод истечения срока действия:
cache = caffeine.newbuilder ().
Чтобы инициализировать пользовательскую политику, нам необходимо реализовать интерфейс срока действия:
cache = caffeine.newbuilder (). oxriefterter (новый истечение <string, dataobject> () {@Override public long ocireftercreate (String Key, значение DataObject, Long CurishTime) {return Value.getData (). Length () * 1000;} @Override public groviefiture CurrentDuration;4.3. Переработка на основе ссылки
Мы можем настроить кэш, чтобы включить сборы мусора значений кэшированных ключей. Для этого мы настраиваем ключ и значение как слабые ссылки, и мы можем настроить только мягкие ссылки для сбора мусора.
Когда нет сильных ссылок на объект, использование SleedRefence может обеспечить сбор мусора объектов. Softreference позволяет объектам собирать мусор на основе глобальной политики JVM в наименовании. Для получения более подробной информации о цитатах Java см. Здесь.
Мы должны включить каждый вариант, используя Caffeine.weakkeys (), Caffeine.weakvalues () и Caffeine.softvalues ():
Загрузка Cache <String, dataObject> cache = caffeine.newbuilder (). cache = caffeine.newbuilder ().
5. Обновить
Кэш может быть настроен для автоматического обновления записи после определенного периода времени. Посмотрим, как использовать метод RefreshafterWrite:
Caffeine.newbuilder () .RefreshafterWrite (1, TimeUnit.minutes) .build (k -> dataObject.get («Данные для» + k));
Здесь мы должны понимать разницу между истекающим и обновленным. Когда запрашивается истекшая запись, выполнение будет блокировать, пока функция сборки не вычисляет новое значение.
Однако, если запись может быть обновлена, кэш возвращает старое значение и асинхронно перезагружает значение.
6. Статистика
У кофеина есть способ записать использование кэша:
Загрузка cache <String, dataObject> cache = caffeine.newbuilder () .maximumsize (100) .recordstats () .build (k -> dataobject.get («Данные для» + k); cache.get («a»); cache.get ("a"); assertequals (1, cache.stats (). Hitcount ()); assertequals (1, cache.stats (). misscount ());Мы также можем передать поставщику RecordStats для создания реализации StatScounter. Этот объект выдвигается каждое изменение, связанное с статистикой.
7. Заключение
В этой статье мы знакомы с библиотекой кофеина Java. Мы увидели, как настроить и заполнить кэш, и как выбрать соответствующую политику срока действия или обновления на основе наших потребностей.
Исходный код для примеров в этой статье можно найти на GitHub.
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.