[java] Looking for simple Java in-memory cache

I'm looking for a simple Java in-memory cache that has good concurrency (so LinkedHashMap isn't good enough), and which can be serialized to disk periodically.

One feature I need, but which has proved hard to find, is a way to "peek" at an object. By this I mean retrieve an object from the cache without causing the cache to hold on to the object any longer than it otherwise would have.

Update: An additional requirement I neglected to mention is that I need to be able to modify the cached objects (they contain float arrays) in-place.

Can anyone provide any recommendations?

This question is related to java caching

The answer is


Try this:

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

}

If you're needing something simple, would this fit the bill?

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

It wont save to disk, but you said you wanted simple...

Links:

(As Adam commented, synchronising a map has a performance hit. Not saying the idea doesn't have hairs on it, but would suffice as a quick and dirty solution.)


You can easily use imcache. A sample code is below.

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

Another option for an in-memory java cache is cache2k. The in-memory performance is superior to EHCache and google guava, see the cache2k benchmarks page.

The usage pattern is similar to other caches. Here is an example:

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

If you have google guava as dependency then trying out guava cache, may be a good alternative.


How about this: https://commons.apache.org/proper/commons-jcs/ (updated to new address, as JCS is now in Apache Commons)


Try Ehcache? It allows you to plug in your own caching expiry algorithms so you could control your peek functionality.

You can serialize to disk, database, across a cluster etc...


Try @Cacheable from jcabi-aspects. With a single annotation you make the entire method result cacheable in memory:

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

Also, read this article: http://www.yegor256.com/2014/08/03/cacheable-java-annotation.html


Ehcache is a pretty good solution for this and has a way to peek (getQuiet() is the method) such that it doesn't update the idle timestamp. Internally, Ehcache is implemented with a set of maps, kind of like ConcurrentHashMap, so it has similar kinds of concurrency benefits.