Looking for simple Java in-memory cache [closed]

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?


Since this question was originally asked, Google's Guava library now includes a powerful and flexible cache. I would recommend using this.


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.


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:

  • Collections.synchronizedMap
  • WeakHashMap

(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.)


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.