Singleton

Why is this class needed?

Usually, we use singletons in two ways:

  1. We add a static method getInstance() inside the object to get it. This method can be divided into hungry and lazy modes, as described in the blog post Thread-safe Singleton Pattern.
  2. We use a container like Spring to manage objects uniformly and retrieve them from the object pool when needed. Spring can also determine whether to use the lazy or hungry mode through configuration.

To be honest, I prefer the second approach, but Spring focuses more on injection than retrieval. Therefore, I wanted to create the Singleton class to maintain a singleton pool, so we can directly retrieve the singleton object when needed. Here, I used the lazy mode. I just wanted to change the way singletons are managed. I hope that the singleton is managed by a container tool rather than a large framework, which can greatly reduce the complexity of using singletons.

Usage

/**
 * Singleton example
 * @author loolly
 *
 */
public class SingletonDemo {

    /**
     * Animal interface
     * @author loolly
     *
     */
    public static interface Animal{
        public void say();
    }

    /**
     * Dog implementation
     * @author loolly
     *
     */
    public static class Dog implements Animal{
        @Override
        public void say() {
            System.out.println("Woof woof");
        }
    }

    /**
     * Cat implementation
     * @author loolly
     *
     */
    public static class Cat implements Animal{
        @Override
        public void say() {
            System.out.println("Meow meow");
        }
    }

    public static void main(String[] args) {
        Animal dog = Singleton.get(Dog.class);
        Animal cat = Singleton.get(Cat.class);

        // The singleton object is the same each time it is retrieved unless Singleton.destroy() or remove method is called
        System.out.println(dog == Singleton.get(Dog.class));        //True
        System.out.println(cat == Singleton.get(Cat.class));            //True

        dog.say();        //Woof woof
        cat.say();        //Meow meow
    }
}

Summary

If you are interested, you can take a look at this class. The implementation is very simple, with a HashMap used as the singleton object pool. Objects are instantiated through newInstance() (which does not support constructor methods with parameters), and both retrieving and creating objects are thread-safe (there may be a bottleneck when the number of singletons is very large and instantiating singletons is very time-consuming). Considering the double-checked locking in get, it is not thread-safe, so the synchronized modifier is directly added. Suggestions are welcome.