Singleton mode: To ensure that only one instance of a class in the system is generated, mainly to solve the frequent creation and destruction of a globally used class.
benefit
- Time benefit - Omits the time to frequently create an object of a common class
- Space benefits - reduce memory usage frequency, reduce GC pressure
Singleton pattern role
Role | effect |
---|---|
singleton class | Provides a factory for singletons, returning singletons |
user | Get and use a singleton class object |
Notice
1. A singleton class can only have one instance.
2. A singleton class must create its own unique instance by itself.
3. The singleton class must provide this instance to all other objects.
Hungry Chinese
Advantages: no locks, higher execution efficiency!
Disadvantages: Initialize when the class is loaded, wasting memory!
Based on the classloader mechanism to avoid multi-threaded synchronization problems, the instance is instantiated when the class is loaded, and the lazy loading effect cannot be achieved!
public class Singleton { private Singleton (){} // private ensures that the singleton will not be instantiated within other code in the system private static Singleton instance = new Singleton(); // The static ally decorated method is called to instantiate the singleton object when the class is loaded (that is, as long as the class is loaded, the singleton object is automatically instantiated to waste space public static Singleton getInstance() { return instance; } }
lazy
Advantages: The singleton object is only created when the getInstance() method is called for the first time
Disadvantages: In order to ensure thread safety, the volatile and synchronized keywords need to be added to ensure thread safety, but each access needs to be synchronized, which affects performance and consumes more resources
public class LazySingleton { private static volatile LazySingleton instance=null; //Ensure that instance is synchronized in all threads private LazySingleton(){} //private to prevent the class from being instantiated externally public static synchronized LazySingleton getInstance() { //add synchronization before the getInstance method if(instance==null) { instance=new LazySingleton(); } return instance; } } /* Introducing the synchronization keyword in order to use lazy loading reduces system performance*/
lazy refactoring
The singleton pattern uses the inner class to maintain the instance of the singleton, and the inner class is not instantiated when the Singleton is loaded. Only when the getInstance method is called, the inner class will be loaded to initialize the singleton object
Using inner classes to implement singletons can do lazy loading without using synchronization keywords, which is a perfect implementation
public class Singleton { private Singleton(){} // The inner class SingletonHolder implements singleton object initialization private static class SingletonHolder{ private static Singleton singleton = new Singleton(); } public static Singleton getInstance(){ // Call the inner class to get the singleton object directly return SingletonHolder.singleton; } }
example
- DBConnector mocks singleton class
public class DBConnector { private DBConnector(){} // Private constructor, which prohibits the creation of singleton objects in other classes private static class DBConnectorHolder{ private static final DBConnector dbConnector = new DBConnector(); } public static DBConnector getInstance(){ return DBConnectorHolder.dbConnector; } }
- test
public class TestDemo { public static void main(String[] args) { DBConnector dbConnector01 = DBConnector.getInstance(); DBConnector dbConnector02 = DBConnector.getInstance(); System.out.println("dbConnector01 memory address: " + dbConnector01.toString()); System.out.println("dbConnector02 memory address: " + dbConnector02.toString()); System.out.println("dbConnector01 of hashcode: " + dbConnector01.hashCode()); System.out.println("dbConnector02 of hashcode: " + dbConnector02.hashCode()); System.out.println(dbConnector01 == dbConnector02); } } // output dbConnector01 memory address: ink.openmind.base01.DBConnector@1c53fd30 dbConnector02 memory address: ink.openmind.base01.DBConnector@1c53fd30 dbConnector01 of hashcode: 475266352 dbConnector02 of hashcode: 475266352 true