Tuesday, 20 April 2021

Guava: LoadingCache: Load not found values automatically

LoadingCache interface specifies a mechanism to load the non-existed values into the cache. Implementations of this interface are expected to be thread-safe, and can be safely accessed by multiple concurrent threads.

 

Example

LoadingCache<Integer, Employee> empCache = CacheBuilder.newBuilder().maximumSize(500)
.expireAfterWrite(10, TimeUnit.SECONDS).recordStats().build(new CacheLoader<Integer, Employee>() {

	@Override
	public Employee load(Integer key) throws Exception {
		Employee emp = EmployeeService.getObject(key);
		return emp;
	}

});

 

As you see above snippet, I defined a LoadingCache instance by specifying CacheLoader (CacheLoader is used retrieves values, based on a key).

 

When you try to retrieve a value from LoadingCache, it retrun the value if it is already exist in the cache, else it load the value using CacheLoader, cache it and return the value.

 

Find the below working application.

 

Employee.java

 

package com.sample.app.cache.model;

public class Employee {
	private Integer id;
	private String firstName;
	private String lastName;

	public Employee(Integer id, String firstName, String lastName) {
		super();
		this.id = id;
		this.firstName = firstName;
		this.lastName = lastName;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	@Override
	public String toString() {
		return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + "]";
	}

}

EmployeeService.java

package com.sample.app.cache.service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.sample.app.cache.model.Employee;

public class EmployeeService {

	private static Map<Integer, Employee> data = new HashMap<>();

	static {
		data.put(1, new Employee(1, "Krishna", "Gurram"));
		data.put(2, new Employee(2, "Lahari", "G"));
		data.put(3, new Employee(3, "Gopi", "Battu"));
	}

	public static Employee getObject(Integer key) throws InterruptedException {
		System.out.println("Loading object with id " + key + " from database....");
		TimeUnit.SECONDS.sleep(2);
		return data.get(key);
	}
}


HelloWorld.java

package com.sample.app.cache;

import java.util.Arrays;
import java.util.List;
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.CacheStats;
import com.google.common.cache.LoadingCache;
import com.sample.app.cache.model.Employee;
import com.sample.app.cache.service.EmployeeService;

public class HelloWorld {
	private static void printEmployee(Employee emp, Integer id) {
		if (emp == null) {
			System.out.println("Employee not exist for the id " + id);
			return;
		}
		System.out.println(emp);
	}

	private static void getAndPrintObjects(LoadingCache<Integer, Employee> empCache, List<Integer> empIds)
			throws ExecutionException {

		for (Integer id : empIds) {
			Employee emp = empCache.get(id);
			printEmployee(emp, id);
		}
	}

	public static void main(String args[]) throws InterruptedException, ExecutionException {

		LoadingCache<Integer, Employee> empCache = CacheBuilder.newBuilder().maximumSize(500)
				.expireAfterWrite(10, TimeUnit.SECONDS).recordStats().build(new CacheLoader<Integer, Employee>() {

					@Override
					public Employee load(Integer key) throws Exception {
						Employee emp = EmployeeService.getObject(key);
						return emp;
					}

				});

		System.out.println("Getting employee with ids 1, 2 and 3 from empCache");
		getAndPrintObjects(empCache, Arrays.asList(1, 2, 3));

		System.out.println("\nGoing to sleep for 2 seconds\n");
		TimeUnit.SECONDS.sleep(2);
		System.out.println("Getting employee with ids 1, 2 and 3 from empCache");
		getAndPrintObjects(empCache, Arrays.asList(1, 2, 3));

		System.out.println("\nGoing to sleep for 2 seconds\n");
		TimeUnit.SECONDS.sleep(2);
		System.out.println("Getting employee with ids 1, 2 and 3 from empCache");
		getAndPrintObjects(empCache, Arrays.asList(1, 2, 3));

		System.out.println("\nGoing to sleep for 8 seconds, so cache will expire\n");
		TimeUnit.SECONDS.sleep(8);
		System.out.println("Getting employee with ids 1, 2 and 3 from empCache");
		getAndPrintObjects(empCache, Arrays.asList(1, 2, 3));
		
	}

}


Output

Getting employee with ids 1, 2 and 3 from empCache
Loading object with id 1 from database....
Employee [id=1, firstName=Krishna, lastName=Gurram]
Loading object with id 2 from database....
Employee [id=2, firstName=Lahari, lastName=G]
Loading object with id 3 from database....
Employee [id=3, firstName=Gopi, lastName=Battu]

Going to sleep for 2 seconds

Getting employee with ids 1, 2 and 3 from empCache
Employee [id=1, firstName=Krishna, lastName=Gurram]
Employee [id=2, firstName=Lahari, lastName=G]
Employee [id=3, firstName=Gopi, lastName=Battu]

Going to sleep for 2 seconds

Getting employee with ids 1, 2 and 3 from empCache
Employee [id=1, firstName=Krishna, lastName=Gurram]
Employee [id=2, firstName=Lahari, lastName=G]
Employee [id=3, firstName=Gopi, lastName=Battu]

Going to sleep for 8 seconds, so cache will expire

Getting employee with ids 1, 2 and 3 from empCache
Loading object with id 1 from database....
Employee [id=1, firstName=Krishna, lastName=Gurram]
Loading object with id 2 from database....
Employee [id=2, firstName=Lahari, lastName=G]
Loading object with id 3 from database....
Employee [id=3, firstName=Gopi, lastName=Battu]






 

 

  

Previous                                                    Next                                                    Home

No comments:

Post a Comment