Op zoek naar een eenvoudige Java-cache in het geheugen

Ik ben op zoek naar een eenvoudige Java-cache in het geheugen met een goede concurrency (dus LinkedHashMap is niet goed genoeg) en die periodiek naar schijf kan worden geserialiseerd.

Een functie die ik nodig heb, maar die moeilijk te vinden is, is een manier om naar een object te “gluren”. Hiermee bedoel ik het ophalen van een object uit de cache zonder dat de cache het object langer vasthoudt dan anders het geval zou zijn geweest.

Update:een extra vereiste die ik heb vergeten te vermelden, is dat ik de objecten in de cache (ze bevatten float-arrays) ter plaatse moet kunnen wijzigen.

Kan iemand aanbevelingen doen?


Antwoord 1, autoriteit 100%

Sinds deze vraag oorspronkelijk werd gesteld, bevat Google’s Guava-bibliotheeknu een krachtige en flexibele cache. Ik zou aanraden dit te gebruiken.


Antwoord 2, autoriteit 56%

Ehcacheis hier een redelijk goede oplossing voor en heeft een manier om te gluren (getQuiet()is de methode), zodat het werkt de inactieve tijdstempel niet bij. Intern is Ehcache geïmplementeerd met een set kaarten, een beetje zoals ConcurrentHashMap, dus het heeft vergelijkbare soorten gelijktijdigheidsvoordelen.


Antwoord 3, autoriteit 41%

Als je iets eenvoudigs nodig hebt, zou dit dan passen?

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

Het wordt niet op schijf opgeslagen, maar je zei dat je eenvoudig wilde…

Links:

(Zoals Adam opmerkte, heeft het synchroniseren van een kaart een prestatiehit. Ik wil niet zeggen dat er geen haren op het idee zitten, maar het zou voldoende zijn als een snelle en vuile oplossing.)


Antwoord 4, autoriteit 31%

Een andere optie voor een in-memory java-cache is cache2k.
De prestaties in het geheugen zijn superieur aan EHCache en google guava, zie de cache2k benchmarks-pagina.

Het gebruikspatroon is vergelijkbaar met andere caches. Hier is een voorbeeld:

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

Als je google guava als afhankelijkheid hebt, kan het uitproberen van guava cache een goed alternatief zijn.


Antwoord 5, autoriteit 15%

Je kunt gemakkelijk imcachegebruiken. Hieronder vindt u een voorbeeldcode.

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

Antwoord 6, autoriteit 15%

Probeer @Cacheablevan jcabi-aspects. Met een enkele annotatie maakt u het gehele resultaat van de methode cachebaar in het geheugen:

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

Lees ook dit artikel: http://www. yegor256.com/2014/08/03/cacheable-java-annotation.html


Antwoord 7, autoriteit 13%

Probeer dit:

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

Antwoord 8, Autoriteit 4%

Hoe zit het met dit: https://commons.apache.org/proper/commons- JCS / (bijgewerkt naar nieuw adres, omdat JCS nu in Apache Commons is)


Antwoord 9

Probeer ehcache ? Hiermee kunt u uw eigen caching-vervalgroep algoritmen aansluiten, zodat u uw PEEK-functionaliteit kunt beheersen.

U kunt serialiseren op schijf, database, over een cluster enz …

Other episodes