Friday 12 July 2013

Caching Implementation Using Core Java



How to implement caching using core java?


Question: - What is Caching?

Answer: - Caching is a temporary location where we can preserve data which is frequently needed, so that we can retrieve the common data in a faster way, as fetching the original data again and again from database is very expensive and it will decrease the performance also. Caching can be mostly used as a performance optimization technique

Question: - What is Object Caching?

Answer: - Object Caching is a way, where the Java objects (entities) are themselves cached. The advantage of an object cache is that the data is cached in the same format that it is used in Java. So no conversion is required during a cache hit as everything is stored at the object-level.

It is possible to cache transient data with the help of object cache technique. This may occur automatically, or may require some effort. If the requirement is like that we don’t have to be cached the transient data then we need to clear that data when the object gets cached.

Question: - What is cache hit?

Answer: - When our application gets a request from client then it will need to access the required data in our storage (database), but it should check the cache first. If the required data is available in cache and entry is found with the requested matching tag (like employee Id), then that entry is used instead of hitting database. This process is termed as cache hit (It is the primary measurement for the caching effectiveness). And the percentage of accesses that result in cache hits is known as the hit rate or hit ratio.

Question: - What is cache miss?

Answer: - When our application gets a request from client then it will need to access the required data in our storage (database), but it should check the cache first. If the required data is not available in cache and entry is not found with the requested matching tag, then this process is termed as cache miss.

If a cache miss occur, then how to handle this situation, below are the two solutions for handling this scenario’s:-

First solution:  If cache didn’t reach its limit and there is free space in the cache then in this case the object that is missing in the cache and forcing the cache miss scenario, will be retrieved from database or other storage and then it should be get inserted into the cache.

Second solution: If cache reached its capacity and there is no free space in the cache then the object that cause cache miss will be fetched from the database or other storage and then we will have to decide which object in the cache we need to remove in order to place our newly created object then we have to use some algorithm which is something like replacement policy (caching algorithms) that decide which entry will be remove to make more room which will be discussed below.

There are many different caching types. The most common is a LRU cache, or one that removes the Least Recently Used objects and maintains a fixed size number of MRU (Most Recently Used) objects.


Question: - How to implement caching using core java?


Answer:-  

A sample example of caching implementation using core java.


System Requirements:-


         Eclipse Editor or any other.
         JDK 1.5 or higher (I am using jdk 1.7.0_03)
         No additional jars are required.

 Steps for creating Eclipse java project for implementing Java Caching:-


  • Create a java project in eclipse.
  • Create a package in the src folder with the name as com.gaurav.cachinginjava.example.
  • Create the JavaCache.java, Product.java, ProductManager.java, ProductManager1.java and JavaCacheManager.java files in this package and place the corresponding below available code in those files.
  • Execute the ProductManager.java and  ProductManager1.java by selecting the option Run as Java Application.

This is the first way to implement caching in java.


JavaCache.java

package com.gaurav.cachinginjava.example;

import java.util.Map;
import java.util.TreeMap;

public class JavaCache {

      private static Map<String, Object> cache = new TreeMap<String, Object>();

      public static synchronized void addCache(String key, Object value) {
            cache.put(key, value);
      }

      public static Object getFromCache(String key) throws NullPointerException {
            return cache.get(key);
      }

      public static synchronized void remove(String key) {
            cache.remove(key);
      }

      public static Map getAll() {
            return cache;
      }
}


Product.java


package com.gaurav.cachinginjava.example;

public class Product implements java.io.Serializable {
      /**
     *
     */
      private static final long serialVersionUID = -5372772868069600498L;
      private String productId;
      private String productName;
      private String productMaker;

      public Product() {

      }

      public Product(String prodId, String prodName, String prodMaker) {
            this.productId = prodId;
            this.productName = prodName;
            this.productMaker = prodMaker;
      }

      /**
       * @return the productId
       */
      public String getProductId() {
            return productId;
      }

      /**
       * @param productId
       *            the productId to set
       */
      public void setProductId(String productId) {
            this.productId = productId;
      }

      /**
       * @return the productName
       */
      public String getProductName() {
            return productName;
      }

      /**
       * @param productName
       *            the productName to set
       */
      public void setProductName(String productName) {
            this.productName = productName;
      }

      /**
       * @return the productMaker
       */
      public String getProductMaker() {
            return productMaker;
      }

      /**
       * @param productMaker
       *            the productMaker to set
       */
      public void setProductMaker(String productMaker) {
            this.productMaker = productMaker;
      }

      @Override
      public String toString() {
            return productName + " made by " + productMaker + " and Model No is : "
                        + productId;
      }

}



ProductManager.java


package com.gaurav.cachinginjava.example;

public class ProductManager {
      private JavaCache javaCache;

      @SuppressWarnings("static-access")
      public ProductManager() {
            try {

                  // Initializing the cache by putting two product data into cache.
                  javaCache.addCache("KDL-32EX650", new Product("KDL-32EX650",
                              "BRAVIA Full HD with Edge LED", "SONY"));
                  javaCache.addCache("72LM9500", new Product("72LM9500",
                              "Full HD LED 3D Smart TV", "LG"));

            } catch (Exception e) {
                  e.printStackTrace();
            }
      }

      @SuppressWarnings("static-access")
      public void addProductInCache(Product product) {
            try {
                  javaCache.addCache(product.getProductId(), product);
            } catch (Exception e) {
                  e.printStackTrace();
            }
      }

      @SuppressWarnings("static-access")
      public Product getProductById(String productId) {
            return (Product) javaCache.getFromCache(productId);
      }

      @SuppressWarnings("static-access")
      public void removeProductFromCache(String productId) {
            try {
                  javaCache.remove(productId);
            } catch (Exception e) {
                  e.printStackTrace();
            }
      }

      public static void main(String[] args) {
            // Creating the ProductManager instance
            ProductManager productManager = new ProductManager();

            // Adding one more product data in the cache.
            productManager.addProductInCache(new Product("UA85S9AR",
                        "Smart TV 2.0", "Samsung"));

            // Getting all the products details which is added in cache

            Product product = productManager.getProductById("KDL-32EX650");
            System.out.println("The First Product retrieved from cache is :- "
                        + product);

            product = productManager.getProductById("72LM9500");
            System.out.println("The Second Product retrieved from cache is :- "
                        + product);

            product = productManager.getProductById("UA85S9AR");
            System.out.println("The Third Product retrieved from cache is :- "
                        + product);

            // Removing a product from the productManager
            productManager.removeProductFromCache("KDL-32EX650");

            // Cross checking that the removed product is still available or not.
            System.out
                        .println("\n**********************************************************************************************");
            System.out
                        .println("Again trying to retrieve the First product from the cache after removing the First product:- "
                                    + productManager.getProductById("KDL-32EX650"));
            System.out
                        .println("**********************************************************************************************\n");

            System.out
                        .println("Again trying to retrieve the Second product from the cache after removing the First product:- "
                                    + productManager.getProductById("72LM9500"));

            System.out
                        .println("Again trying to retrieve the Third product from the cache after removing the First product:- "
                                    + productManager.getProductById("UA85S9AR"));

      }
}

This is the another way to implement caching in java.


JavaCacheManager.java


package com.gaurav.cachinginjava.example;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;

public class JavaCacheManager {

      private static JavaCacheManager javaCacheManagerInstance;
      private static Object objectMonitor = new Object();
      private final Map<String, Object> cache = Collections
                  .synchronizedMap(new LinkedHashMap<String, Object>());

      private JavaCacheManager() {
      }

      public static JavaCacheManager getInstance() {
            if (javaCacheManagerInstance == null) {
                  synchronized (objectMonitor) {
                        if (javaCacheManagerInstance == null) {
                              javaCacheManagerInstance = new JavaCacheManager();
                        }
                  }
            }
            return javaCacheManagerInstance;
      }

      public void addInCache(String cacheKey, Object value) {
            cache.put(cacheKey, value);
      }

      public Object retrieveFromCache(String cacheKey) {
            return cache.get(cacheKey);
      }

      public void clearCache(String cacheKey) {
            cache.put(cacheKey, null);
      }

      public void removeDataFromCache() {
            cache.clear();
      }

}


Product.java


package com.gaurav.cachinginjava.example;

public class Product implements java.io.Serializable {
      /**
     *
     */
      private static final long serialVersionUID = -5372772868069600498L;
      private String productId;
      private String productName;
      private String productMaker;

      public Product() {

      }

      public Product(String prodId, String prodName, String prodMaker) {
            this.productId = prodId;
            this.productName = prodName;
            this.productMaker = prodMaker;
      }

      /**
       * @return the productId
       */
      public String getProductId() {
            return productId;
      }

      /**
       * @param productId
       *            the productId to set
       */
      public void setProductId(String productId) {
            this.productId = productId;
      }

      /**
       * @return the productName
       */
      public String getProductName() {
            return productName;
      }

      /**
       * @param productName
       *            the productName to set
       */
      public void setProductName(String productName) {
            this.productName = productName;
      }

      /**
       * @return the productMaker
       */
      public String getProductMaker() {
            return productMaker;
      }

      /**
       * @param productMaker
       *            the productMaker to set
       */
      public void setProductMaker(String productMaker) {
            this.productMaker = productMaker;
      }

      @Override
      public String toString() {
            return productName + " made by " + productMaker + " and Model No is : "
                        + productId;
      }

}


ProductManager1.java


package com.gaurav.cachinginjava.example;

public class ProductManager1 {
      private JavaCacheManager javaCacheManager;

      public ProductManager1() {
            try {
                  // Loading the cache using the getInstance() method.
                  javaCacheManager = JavaCacheManager.getInstance();

                  // Initializing the cache by putting two product data into cache.
                  javaCacheManager.addInCache("KDL-32EX650", new Product("KDL-32EX650",
                              "BRAVIA Full HD with Edge LED", "SONY"));
                  javaCacheManager.addInCache("72LM9500", new Product("72LM9500",
                              "Full HD LED 3D Smart TV", "LG"));

            } catch (Exception e) {
                  e.printStackTrace();
            }
      }

      public void addProductInCache(Product product) {
            try {
                  javaCacheManager.addInCache(product.getProductId(), product);
            } catch (Exception e) {
                  e.printStackTrace();
            }
      }

      public Product getProductById(String productId) {
            return (Product) javaCacheManager.retrieveFromCache(productId);
      }

      public void removeProductFromCache(String productId) {
            try {
                  javaCacheManager.clearCache(productId);
            } catch (Exception e) {
                  e.printStackTrace();
            }
      }

      public static void main(String[] args) {
            // Creating the ProductManager instance
            ProductManager1 productManager = new ProductManager1();

            // Adding one more product data in the cache.
            productManager.addProductInCache(new Product("UA85S9AR",
                        "Smart TV 2.0", "Samsung"));

            // Getting all the products details which is added in cache

            Product product = productManager.getProductById("KDL-32EX650");
            System.out.println("The First Product retrieved from cache is :- "
                        + product);

            product = productManager.getProductById("72LM9500");
            System.out.println("The Second Product retrieved from cache is :- "
                        + product);

            product = productManager.getProductById("UA85S9AR");
            System.out.println("The Third Product retrieved from cache is :- "
                        + product);

            // Removing a product from the productManager
            productManager.removeProductFromCache("KDL-32EX650");

            // Cross checking that the removed product is still available or not.
            System.out
                        .println("\n**********************************************************************************************");
            System.out
                        .println("Again trying to retrieve the First product from the cache after removing the First product:- "
                                    + productManager.getProductById("KDL-32EX650"));
            System.out
                        .println("**********************************************************************************************\n");

            System.out
                        .println("Again trying to retrieve the Second product from the cache after removing the First product:- "
                                    + productManager.getProductById("72LM9500"));

            System.out
                        .println("Again trying to retrieve the Third product from the cache after removing the First product:- "
                                    + productManager.getProductById("UA85S9AR"));

      }
}


Result:-

The First Product retrieved from cache is :- BRAVIA Full HD with Edge LED made by SONY and Model No is : KDL-32EX650
The Second Product retrieved from cache is :- Full HD LED 3D Smart TV made by LG and Model No is : 72LM9500
The Third Product retrieved from cache is :- Smart TV 2.0 made by Samsung and Model No is : UA85S9AR

**********************************************************************************************
Again trying to retrieve the First product from the cache after removing the First product:- null
**********************************************************************************************

Again trying to retrieve the Second product from the cache after removing the First product:- Full HD LED 3D Smart TV made by LG and Model No is : 72LM9500
Again trying to retrieve the Third product from the cache after removing the First product:- Smart TV 2.0 made by Samsung and Model No is : UA85S9AR
 


No comments:

Post a Comment