Introducing the Google Guava Cache

Google Guava is a library packed with useful stuff that can be very handy in almost any Java project, including libraries for immutable collections, functional programming, I/O and much more. I have been taking the Guava Cache library for a spin, and I will definitely have much use for it in future projects.

At first glance, the Guava Cache doesn’t look very different from the caches that you probably have written so many times in the past – a fancy Cache class on top of a HashMap with some timeout functionality. Except from now on, you don’t have to reinvent the wheel. Digging a little deeper, the Guava Cache also offers different expiration behaviors, along with other features that might come in handy.

The Guava Cache is an incremental cache, in the sense that when you request an object from the cache, it checks to see if it already has the corresponding value for the supplied key. If it does, it simply returns it (assuming it hasn’t expired). If it doesn’t already have the value, it uses a CacheLoader to fetch the value and then it stores the value in the cache and returns it. This way, the cache is growing as new values are requested.

The only thing you need to provide is the implementation for the abstract load method of the CacheLoader class. This is the method that is used to fetch the value to be cached. You can do this as an anonymous class, but creating a new class that extends CacheLoader is the way I prefer to do it (it’s cleaner and helps when unit testing/mocking). Please note that this method is expected to never return null, or there is no way for the Cache to tell whether this record has not been fetched yet or if it’s value is just empty.

So let’s not waste another minute – let’s get our hands dirty with the Guava Cache! You will need the Guava jar file, which can be downloaded from the Guava website. Or, if you’re using maven, just include this dependency in your pom:

The next thing you need to do is to create the Cache object. Caches are created using the CacheBuilder. Let’s look at a basic example of a cache with keys of type String holding Object values:

If we request an Object that is not yet stored in the cache, a new object is simply created by our CacheLoader object. In real life, however, you would probably be digging the value out from something like a database or perhaps a web service.

Using the CacheBuilder, you can specify the characteristics of the cache, like timeouts, max size and other properties. The build() method then takes your CacheLoader as the only argument.

In the next example we will create a cache that holds Animal objects, with a timeout of 5 minutes. This is our very basic non-fancy Animal class:

Let’s create a cache for our Animals:

The maximum size of the cache is set to 1000 objects. When that limit is reached, the cache will begin to evict the objects that are not recently used (actually, the Guava Cache may start dropping objects before the maximum is reached, see Kevin’s comment explaining this).

expireAfterWrite lets us decide how long a cached Animal may live, before it is considered too old and thrown away. We could also set another timeout value using the expireAfterAccess method, which tells the cache to throw away values that has not been read (or written) in a certain amount of time.

The AnimalCacheLoader class is the class responsible for populating the cache, and extends the abstract Guava class CacheLoader:

This is enough to make the cache work. To get an Animal from the cache, simply use the get method:

This piece of code will print:

and it will place our new monkey in the cache.

As you can see, the Guava Cache is really simple to use, and it can save us time not having to write our own logic for the caching. And if you trust the Google Guava team enough, you don’t have to write unit tests for your cache either (but it could possibly be a good idea to write tests for your CacheLoader.load implementation).

The Guava Cache also has some nice statistics build in, which can be very handy if you want to know how and if your cache is really used. Just call the stats method on the cache and it will give you a nice CacheStats object which has all the numbers you’ll need.

That’s my breif introduction to the basics of the Google Guava Cache. I hope you will find it useful. Read more about Guava at the Guava Project Homepage.

This Post Has 8 Comments

  1. “actually, the Guava Cache tries to be smart and starts deleting records when the number of records is getting close to the maximum.”

    I… wouldn’t exactly describe it that way. It’s not trying to be smart. It’s just that currently, the maximum is checked _per-segment_. You’re using the default of 4 segments, so there are really 4 separate limits of 250; if _any_ one of them gets up to 251 something will be evicted, whether the entire cache exceeded 1000 or not.

  2. “And if you trust the Google Guava team enough, you don’t have to write unit tests for your cache either.”

    To be fair, Guava’sCache implementation is used in Google production services, which is a pretty strong argument that it’s survived extensive usage in the real world.

  3. @Kevin: Thanks for the explanation! Updated the post.

    @Louis: I totally agree with you.

  4. tks! very nice post , it gives me a clear view of Guava Cache ! :D

  5. Great post! Thank you :)

Leave a Reply

Close Menu