Ищу простой Java-кэш в памяти [закрыт]
Я ищу простой Java-кэш в памяти, который имеет хороший параллелизм (поэтому LinkedHashMap недостаточно хорош), и который может быть сериализован на диск периодически.
одна особенность мне нужна, но которая оказалась трудно найти, это способ "заглянуть" на объект. Под этим я подразумеваю извлечение объекта из кэша, не заставляя кэш удерживать объект дольше, чем это было бы в противном случае.
обновление: дополнительным требованием Я пренебрег следует отметить, что мне нужно иметь возможность изменять кэшированные объекты (они содержат массивы с плавающей точкой) на месте.
может кто-нибудь дать какие-либо рекомендации?
9 ответов:
Так как этот вопрос был первоначально задан, библиотека гуавы от Google теперь включает в себя мощный и гибкий кэша. Я бы рекомендовал использовать это.
Ehcache это довольно хорошее решение для этого и имеет способ заглянуть (getQuiet() это метод) такой, что он не обновляет метку времени простоя. Внутренне Ehcache реализован с набором карт, вроде ConcurrentHashMap,поэтому он имеет аналогичные преимущества параллелизма.
Если вам нужно что-то простое, будет ли это подходит?
Map<K, V> myCache = Collections.synchronizedMap(new WeakHashMap<K, V>());
он не будет сохранять на диск, но вы сказали, что хотите просто...
ссылки:
(как заметил Адам, синхронизация карты имеет хит производительности. Не говоря уже о том, что идея не имеет волос на нем, но было бы достаточно как быстрое и грязное решение.)
другой вариант для кэша java в памяти -cache2k. Производительность в памяти превосходит EHCache и google guava, см. страница тестов cache2k.
шаблон использования похож на другие кэши. Вот пример:
Cache<String,String> cache = new Cache2kBuilder<String, String>() {} .expireAfterWrite(5, TimeUnit.MINUTES) // expire/refresh after 5 minutes .resilienceDuration(30, TimeUnit.SECONDS) // cope with at most 30 seconds // outage before propagating // exceptions .refreshAhead(true) // keep fresh when expiring .loader(new CacheLoader<String, String>() { @Override public String load(final String key) throws Exception { return ....; } }) .build(); String val = cache.peek("something"); cache.put("something", "hello"); val = cache.get("something");
Если у вас есть google guava в качестве зависимости, то попробуйте Guava cache, может быть хорошей альтернативой.
вы можете легко использовать imcache. Пример кода приведен ниже.
void example(){ Cache<Integer,Integer> cache = CacheBuilder.heapCache(). cacheLoader(new CacheLoader<Integer, Integer>() { public Integer load(Integer key) { return null; } }).capacity(10000).build(); }
попробуйте это:
import java.util.*; public class SimpleCacheManager { private static SimpleCacheManager instance; private static Object monitor = new Object(); private Map<String, Object> cache = Collections.synchronizedMap(new HashMap<String, Object>()); private SimpleCacheManager() { } public void put(String cacheKey, Object value) { cache.put(cacheKey, value); } public Object get(String cacheKey) { return cache.get(cacheKey); } public void clear(String cacheKey) { cache.put(cacheKey, null); } public void clear() { cache.clear(); } public static SimpleCacheManager getInstance() { if (instance == null) { synchronized (monitor) { if (instance == null) { instance = new SimpleCacheManager(); } } } return instance; } }
попробовать
@Cacheable
С jcabi-аспекты. С помощью одной аннотации вы делаете весь результат метода кэшируемым в памяти:public class Resource { @Cacheable(lifetime = 5, unit = TimeUnit.SECONDS) public String load(URL url) { return url.openConnection().getContent(); } }
кроме того, прочитайте эту статью: http://www.yegor256.com/2014/08/03/cacheable-java-annotation.html
Как насчет этого:https://commons.apache.org/proper/commons-jcs/ (обновлено до нового адреса, так как JCS теперь находится в Apache Commons)
попробовать Ehcache? Это позволяет вам подключать свои собственные алгоритмы истечения срока действия кэширования, чтобы вы могли контролировать свою функциональность peek.
вы можете сериализовать на диск, базы данных в кластере и т. д...