Guava LoadingCache Example: Demoed With Java8 Duration and Instant

Guava LoadingCache is a very convenient utility for caching key based value for performance improvement. Whenever you have an expensive object or calculation can be identified with a key, you always should consider to cache it in one way or another, especially on the system where the memory is relatively abundant.

Here below is a very simple program to demonstrate the LoadingCache. To run it, you need to put Guava jar on the classpath.

package test;

import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

public class Test {

  // Create a cache
  private static final LoadingCache<String, ExpensiveObject> cache = CacheBuilder
      .newBuilder().maximumSize(5).expireAfterAccess(5, TimeUnit.MINUTES)
      .build(new CacheLoader<String, ExpensiveObject>() {

        @Override
        public ExpensiveObject load(String id) throws Exception {
          return ExpensiveObject.getInstance(id);
        }
      });

  public static void main(String[] args) throws IOException, ExecutionException {
    Instant t0 = Instant.now();
    Test.cache.get("a");
    Instant t1 = Instant.now();
    Test.cache.get("b");
    Instant t2 = Instant.now();
    Test.cache.get("a");
    Instant t3 = Instant.now();
    Test.cache.get("b");
    Instant t4 = Instant.now();
    Test.cache.get("c");
    Instant t5 = Instant.now();
    System.out.println("First time for a used " + Duration.between(t0, t1).toMillis());
    System.out.println("First time for b used " + Duration.between(t1, t2).toMillis());
    System.out.println("Second time for a used " + Duration.between(t2, t3).toMillis());
    System.out.println("Second time for b used " + Duration.between(t3, t4).toMillis());
    System.out.println("First time for c used " + Duration.between(t4, t5).toMillis());
  }

  public static class ExpensiveObject{
    private final String id;

    private ExpensiveObject(String id) throws InterruptedException {
      //Simulate an expensive operation, such as database access or network downloading, etc
      TimeUnit.SECONDS.sleep(5);
      this.id=id;
    }

    public static ExpensiveObject getInstance(String id) throws InterruptedException {
      return new ExpensiveObject(id);
    }
  }
}

The output of the execution should be

First time for a used 5008
First time for b used 5001
Second time for a used 0
Second time for b used 0
First time for c used 5000

The LoadingCache is very easy to configure. The maximum number of cached entries is specified by maximumSize(int), and the cached entry expiration duration is specified by expireAfterAccess(int, TimeUnit). When configuring, you should take your application’s nature into consideration. For example how much heap you can afford for caching and how frequent the cached objects mutate.

Advertisements
This entry was posted in Java and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s