web-dev-qa-db-fra.com

Recherche d'un simple Java cache en mémoire

Je recherche un simple Java qui présente une bonne concurrence (donc LinkedHashMap n'est pas assez bon)) et qui peut être sérialisé périodiquement sur le disque.

Une fonction dont j'ai besoin, mais qui s’est révélée difficile à trouver, est un moyen de "jeter un coup d’œil" sur un objet. J'entends par là récupérer un objet dans le cache sans lui faire tenir plus longtemps que cela n'aurait été le cas autrement.

Mise à jour: Une exigence supplémentaire que j'ai omis de mentionner est que je dois être capable de modifier les objets mis en cache (ils contiennent des tableaux flottants) sur place.

Quelqu'un peut-il fournir des recommandations?

90
sanity

Depuis que cette question a été posée à l'origine, la bibliothèque Google de Guava inclut désormais un cache puissant et flexible. Je recommanderais d'utiliser ceci.

53
sanity

Ehcache est une très bonne solution pour cela et a un moyen de jeter un œil ( getQuiet () est la méthode) de sorte qu'il ne mette pas à jour l'horodatage d'inactivité. En interne, Ehcache est implémenté avec un ensemble de cartes, un peu comme ConcurrentHashMap, ce qui lui confère des avantages similaires en termes de concurrence.

36
Alex Miller

Si vous avez besoin de quelque chose de simple, est-ce que cela conviendrait?

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

Il ne sera pas enregistré sur le disque, mais vous avez dit que vous vouliez simple ...

Liens:

(Comme Adam a commenté, la synchronisation d'une carte a un impact sur les performances. Ne pas dire que l'idée n'a pas de poils sur elle, mais suffirait comme une solution rapide et sale.)

19
Evan

Une autre option pour un cache en mémoire Java le cache est cache2k . Les performances en mémoire sont supérieures à EHCache et à Google Guava, voir la page des repères cache2k .

Le modèle d'utilisation est similaire aux autres caches. Voici un exemple:

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");

Si vous avez une dépendance de google gava, essayez alors le cache de goyave, cela pourrait être une bonne alternative.

15
cruftex

Vous pouvez facilement utiliser imcache . Un exemple de code est ci-dessous.

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

Essayez @Cacheable de jcabi-aspects . Avec une seule annotation, vous pouvez mettre en mémoire tout le résultat de la méthode:

public class Resource {
  @Cacheable(lifetime = 5, unit = TimeUnit.SECONDS)
  public String load(URL url) {
    return url.openConnection().getContent();
  }
}

Lisez également cet article: http://www.yegor256.com/2014/08/03/cacheable-Java-annotation.html

8
yegor256

Essaye ça:

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

}
8
Serhii Bohutskyi

Que diriez-vous de ceci: https://commons.Apache.org/proper/commons-jcs/ (mis à jour à la nouvelle adresse, car JCS est maintenant dans Apache Commons)

3
TofuBeer

Essayez Ehcache ? Il vous permet de brancher vos propres algorithmes d’expiration de la mise en cache afin de contrôler votre fonctionnalité de coup d’œil.

Vous pouvez sérialiser sur un disque, une base de données, sur un cluster, etc.

0
Stephen