Поиск простого кэша Java в памяти

Я ищу простой кэш Java в памяти, который имеет хороший concurrency (поэтому LinkedHashMap не достаточно хорош) и периодически может быть сериализован на диск.

Одна особенность, которая мне нужна, но которая оказалась трудно найти, - это способ "заглянуть" в объект. Под этим я подразумеваю получение объекта из кеша, не заставляя кеш удерживать объект дольше, чем это было бы иначе.

Обновление: Дополнительным требованием, о котором я не упоминал, является то, что мне нужно иметь возможность изменять кэшированные объекты (они содержат массивы с плавающей запятой) на месте.

Можно ли предоставить какие-либо рекомендации?

Ответ 1

Поскольку этот вопрос изначально был задан, Google Guava library теперь включает мощный и гибкий кеш. Я бы рекомендовал использовать это.

Ответ 2

Ehcache является довольно хорошим решением для этого и имеет возможность заглянуть (getQuiet() - это метод), так что он не обновляет временную метку времени простоя. Внутри Ehcache реализован с набором карт, вроде ConcurrentHashMap, поэтому он имеет аналогичные преимущества concurrency.

Ответ 3

Если вам нужно что-то простое, это соответствовало бы счету?

Map<K, V> myCache = Collections.synchronizedMap(new WeakHashMap<K, V>());

Это не спасет диск, но вы сказали, что хотите просто...

Ссылки:

(Как заметил Адам, синхронизация карты имеет удар производительности. Не говоря о том, что идея не имеет волосков на ней, но ее хватит как быстрое и грязное решение.)

Ответ 4

Другим вариантом для кэша java в памяти является cache2k.  Производительность в памяти превосходит EHCache и google guava, см. Страницу cache2k benchmarks.

Схема использования похожа на другие кеши. Вот пример:

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, может быть хорошей альтернативой.

Ответ 5

Попробуйте следующее:

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;
    }

}

Ответ 6

Вы можете легко использовать imcache. Ниже приведен пример кода.

void example(){
    Cache<Integer,Integer> cache = CacheBuilder.heapCache().
    cacheLoader(new CacheLoader<Integer, Integer>() {
        public Integer load(Integer key) {
            return null;
        }
    }).capacity(10000).build(); 
}

Ответ 7

Попробуйте @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

Ответ 9

Попробуйте Ehcache? Это позволяет вам подключать собственные алгоритмы завершения кеширования, чтобы вы могли контролировать свои возможности поиска.

Вы можете сериализовать на диск, базу данных, через кластер и т.д.