Recherche d'un cache Java en mémoire simple [fermé]


102

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

Une fonctionnalité dont j'ai besoin, mais qui s'est avérée difficile à trouver, est un moyen de «jeter un coup d'œil» sur un objet. J'entends par là récupérer un objet du cache sans que le cache ne retienne l'objet plus longtemps qu'il ne l'aurait autrement.

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

Quelqu'un peut-il fournir des recommandations?


1
Je recherche quelque chose de similaire qui soit "dans le processus" et plus léger. Je veux l'utiliser pour stocker des données dans un plugin Eclipse dans le tas. Ehcache et JCS semblent trop lourds / distribués / J2EE à mon goût.
Uri

1
duplication possible de l' API Lightweight Java Object Cache
Raedwald

Je recommanderai Apache Ignite ( ignite.apache.org )
Bhagat S.

1
Que cette question soit close (6 ans après les faits) et que les gens se demandent encore aujourd'hui, montre à quel point le système de modérateur de SO échoue.
dustinevan

Réponses:


61

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


3
Veuillez noter que Spring ne prend plus en charge le cache Guava: stackoverflow.com/questions/44175085/...
sinner

@sanity implémente-t-il Jcache?
Gaurav

Caffine est également une bibliothèque de mise en cache agréable et performante. Caffeine est une bibliothèque de mise en cache haute performance presque optimale basée sur Java 8. Caffeine fournit un cache en mémoire utilisant une API inspirée de Google Guava
Slavus

37

Ehcache est une très bonne solution pour cela et a un moyen de voir ( getQuiet () est la méthode) de sorte qu'il ne met pas à jour l'horodatage d'inactivité. En interne, Ehcache est implémenté avec un ensemble de cartes, un peu comme ConcurrentHashMap, il présente donc des avantages similaires en matière de concurrence.


2
Merci, une question supplémentaire: si je récupère un objet d'EHcache (par exemple, un tableau) et le modifie - l'objet sera-t-il mis à jour dans le cache? c'est à dire. EHCache conserve-t-il des références aux objets?
sanity

1
Je pense que oui, mais pour le faire en toute sécurité, vous devez bien sûr verrouiller l'objet de manière appropriée.
Alex Miller

J'adore ehcache, cependant, c'est un pot de 10 Mo. Beaucoup trop gros.
markthegrea

23

Si vous avez besoin de quelque chose de simple, cela conviendrait-il?

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 l'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 dessus, mais qu'elle suffirait comme solution rapide et sale.)


4
Synchroniser une carte gigantesque entière est une pénalité lourde. Vous pouvez facilement stocker des types faibles dans une carte de hachage simultanée et les supprimer périodiquement.
Adam Gent

7
ConcurrentHashMap est meilleur que Collections.synchronizedMap stackoverflow.com/questions/6692008/…
Pablo Moretti

8
En termes de performances, ConcurrentHashMap fonctionne absolument mieux, mais il ne partage pas les propriétés d'un WeakHashMap en ce qui concerne l'autorisation au garbage collector de récupérer de la mémoire. Cela peut être important ou non pour vous.
Evan

4
Ensuite, utilisez ConcurrentHashMap<WeakReference<T>>. docs.oracle.com/javase/7/docs/api/java/lang/ref/…
jdmichal

19

Une autre option pour un cache java en mémoire est cache2k . Les performances en mémoire sont supérieures à EHCache et google guava, voir la page des tests de cache2k .

Le modèle d'utilisation est similaire à celui des 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 google goyave comme dépendance, essayer le cache de goyave peut être une bonne alternative.


cruftex, si je ferme mon application, le cache détruira toutes les données enregistrées ou non?
Menai Ala Eddine - Aladdin

10

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

9

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

}

Les problèmes liés à l'utilisation d'une carte synchronisée ont déjà été abordés dans d'autres réponses.
santé mentale

@sergeyB: Je cherchais une solution similaire qui est simple pour implémenter le cache ... Merci
Prakruti Pathik

1
public static SimpleCacheManager getInstance() {devrait être public synchronized static SimpleCacheManager getInstance() {sinon if (instance == null) {n'est pas thread-safe. Dans ce cas, vous pouvez supprimer l'objet moniteur tous ensemble puisque la synchronisation a lieu pour tous les appels getInstance (), voir: javaworld.com/article/2073352/core-java/…
Can Kavaklıoğlu

Puis-je recommander d'utiliser une énumération pour singleton? dzone.com/articles/java-singletons-using-enum
Erk



0

Essayez Ehcache ? Il vous permet de brancher vos propres algorithmes d'expiration de mise en cache afin que vous puissiez contrôler vos fonctionnalités d'aperçu.

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.