Saturday, May 25, 2013

Singleton

Here's are two examples of creating singletons. One uses lazy loading and the other eagerly creates the instance as soon at the class is loaded. For lazy loading, we need to make sure we're thread safe and prevent two threads from creating two instances.
Also, as an interesting side trick, the two classes memoized results to make repeated calls return the result faster.

Get the code here.

import java.util.HashMap;
import java.util.Map;

/**
 * Gives the nth fibonacci number.
 * It memoizes results so that repeated calls are fast.
 *
 * @author megha
 */
public class MemoizedFibonacci {

        // This is the only instance that we will create, ever!
        private static final MemoizedFibonacci SINGLETON_INSTANCE = new MemoizedFibonacci();

        private final Map<Integer, Long> fibonacciPairs = new HashMap<Integer, Long>();

        // constructor is made private so that no one can create an instance of this class.
        private MemoizedFibonacci() {}

        /**
         * Method to access the only instance of {@link MemoizedFibonacci}.
         */
        public static MemoizedFibonacci getInstance() {
                return SINGLETON_INSTANCE;
        }

        /**
         * @return the {@code n}th fibonacci number, starting with 0 for n=0, 1 for n=1
         */
        public long getNthFibonacci(int n) {
                if (n == 0) return 0;
                if (n == 1) return 1;

                if (fibonacciPairs.containsKey(n)) {
                        return fibonacciPairs.get(n);
                }
                long nthFibonacci = getNthFibonacci(n-1) + getNthFibonacci(n-2);
                fibonacciPairs.put(n, nthFibonacci);
                return nthFibonacci;
        }
}
import java.util.HashMap;
import java.util.Map;

/**
 * Gives the Sum of squares till the nth number.
 * It memoizes the results so that repeated calls are fast.
 *
 * @author megha birmiwal
 */
public class MemoizedSumOfSquares {
// this is lazily loaded
        private static MemoizedSumOfSquares singletonInstance = null;

        private final Map<Integer, Long> sumOfSquarePairs = new HashMap<Integer, Long>();

        private MemoizedSumOfSquares() {}

        // marking it synchronized, to prevent race conditions // i.e. when multiple threads call this at the same time.
        public synchronized MemoizedSumOfSquares getInstance() { // lazy loaded here
                if  (singletonInstance == null) {
                        singletonInstance = new MemoizedSumOfSquares();
                }
                return singletonInstance;
        }

        public long getSumOfSquares(int n) {
                if (n == 0) return 0;
                if (sumOfSquarePairs.containsKey(n)) {
                        return sumOfSquarePairs.get(n);
                }
                long result = getSumOfSquares(n-1) + n*n;
                sumOfSquarePairs.put(n, result);
                return result;
        }
}


No comments:

Post a Comment