35

ehcache is a hugely configurable beast, and the examples are fairly complex, often involving many layers of interfaces.

Has anyone come across the simplest example which just caches something like a single number in memory (not distributed, no XML, just as few lines of java as possible). The number is then cached for say 60 seconds, then the next read request causes it to get a new value (e.g. by calling Random.nextInt() or similar)

Is it quicker/easier to write our own cache for something like this with a singleton and a bit of synchronization?

No Spring please.

wingnut
  • 1,193
  • 2
  • 16
  • 25

2 Answers2

38

EhCache comes with a failsafe configuration that has some reasonable expiration time (120 seconds). This is sufficient to get it up and running.

Imports:

import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

Then, creating a cache is pretty simple:

CacheManager.getInstance().addCache("test");

This creates a cache called test. You can have many different, separate caches all managed by the same CacheManager. Adding (key, value) pairs to this cache is as simple as:

CacheManager.getInstance().getCache("test").put(new Element(key, value));

Retrieving a value for a given key is as simple as:

Element elt = CacheManager.getInstance().getCache("test").get(key);
return (elt == null ? null : elt.getObjectValue());

If you attempt to access an element after the default 120 second expiration period, the cache will return null (hence the check to see if elt is null). You can adjust the expiration period by creating your own ehcache.xml file - the documentation for that is decent on the ehcache site.

Julien Chastang
  • 17,592
  • 12
  • 63
  • 89
jbrookover
  • 5,100
  • 1
  • 23
  • 23
  • Very nice, thanks! However, this does not give anything over a singleton with an (now-updatedat)>timeout check. Ideally the cache should return the old result while it goes off and gets a new one, to avoid all the reading threads being blocked for several seconds. Can ehcache do this, or should I stick with using a singleton and synchronization? Many thanks! – wingnut Jun 08 '11 at 15:26
  • EhCache, as far as I know, doesn't have built in functionality for a timecheck on the last updated. You can either erase the cache entry upon updating, or do your own check before grabbing from the cache. EhCache will have a timestamp of when the object was inserted, so that's done for you. It will also handle removal of infrequently used objects when your cache fills up. Finally, it allows you to do more things in the future, if you choose. But, yes, sometimes writing your own is simpler. – jbrookover Jun 09 '11 at 13:36
  • What if the stored object value in cache itself is null for some reason? – TechnoCrat Jan 05 '15 at 15:20
  • You'd have to add some logic if you care about knowing whether the cache entry is null (not in cache) vs. the data being null. But the system will cache null values, if desired. – jbrookover Jan 06 '15 at 23:12
13

A working implementation of jbrookover's answer:

import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import net.sf.ehcache.Cache;

public class EHCacheDemo  {
    public static final void main(String[] igno_red)  {
        CacheManager cchm = CacheManager.getInstance();

        //Create a cache
        cchm.addCache("test");

        //Add key-value pairs
        Cache cch = cchm.getCache("test");
        cch.put(new Element("tarzan", "Jane"));
        cch.put(new Element("kermit", "Piggy"));

        //Retrieve a value for a given key
        Element elt = cch.get("tarzan");
        String sPartner = (elt == null ? null : elt.getObjectValue().toString());

        System.out.println(sPartner);  //Outputs "Jane"

        //Required or the application will hang
        cchm.removeAllCaches();  //alternatively: cchm.shutdown();
    }
}
aliteralmind
  • 19,847
  • 17
  • 77
  • 108