Devoxx France 2012 – Java Caching with Guava
The Guava Cache library works one level above ConcurrentHashmap but doesn’t offer as much features as Ehcache. Guava caches aren’t pre-loaded by default and are all thread safe. The loading of a cache is done with an implementation of the abstract class CacheLoader.
The build of the cache is done progressively, starting by a call to the static method CacheBuilder.newBuilder(), then chaining calls to methods from class CacheBuilder. This allows to specify its configuration and especially its eviction strategy for values : value accessed least recently with expireAfterAccess(long, TimeUnit), value modified least recently modified with expireAfterWrite(long, TimeUnit) … Besides time goes, eviction of values can be activated by specifying the maximum total weight of the cache with a call to maximumWeight(long), requiring also a call to weigher(Weighter) to indicate how to weigh a cache entry.
The build of the cache terminates by calling build() or build(CacheLoader), which returns a new Cache instance.
Besides classical features, cache statistics can be activated by calling the recordStats() method. Usage of the removalListener(RemovalListener) method allows to know when a value has just been deleted from the cache. By default, this notification is synchronous, which can slow down cache operations. To process notifications asynchronously, you must wrap your RemovalListener by calling RemovalListeners.asynchronous(RemovalListener, Executor). While building the cache, a call to refreshAfterWrite(long, TimeUnit) will schedule an automatic refresh of a value some time after its creation or its last modification. In some cases, it’s more interesting to load all cache values once by overloading the CacheLoader.loadAll(Iterable) method.
Among features, there is Cache.get(K, Callable) to get a value from the cache by specifying how to add it when it’s missing. In this case, a unique call to Callable is done by the cache, even if multiple threads are asking the value for that key. Finally, it’s possible to get a view of the cache as a ConcurrentMap by calling asMap().