Main points
- A class can only have one instance
- Constructor privatization
- It must create the instance itself
- Contains a static variable of this class to hold this unique instance
- This instance must be provided by the whole system.
- Provide external access to the instance object
- Direct exposure
- Get static variables by get method
- Provide external access to the instance object
Common forms
- Starved Chinese style: there is no thread safety problem in directly creating objects
- Direct instantiation of Han style (concise and intuitive)
- Enumerative (simplest)
- Static code block starved Chinese style (suitable for complex instantiation)
- Lazy: delay creating objects
- Thread unsafe (for single thread)
- Thread safety (for multithreading)
- Static internal column form (for multithreading)
- Instantiate the object directly, whether it is needed or not
/* * Hungry man *(1)Constructor privatization *(2)Self created and saved with static variables *(3)Provide this instance to the outside *(4)Emphasize that this is a single example, decorated with final (this variable can only be assigned once, and cannot be modified later) */ public class Singleton1 { public static final Singleton1 INSTANCE = new Singleton1(); private Singleton1 (){ } }
- After enumeration - jdk1.5 - starved Chinese
/* *Hungry man *Enumeration type: there are only a few objects representing this type. *We can limit it to one, and it's a single case. */ public enum Singleton2{ INSTANCE }
- Static code block - starved Chinese style
/* * This method is suitable for those who need to read a bunch of information from the configuration file to instantiate. */ public class Singleton3 { public static final Singleton3 INSTANCE; private String info; static { try { Properties pro = new Properties(); // Read information from the configuration file single.properties located in the src directory pro.load(Sinfleton3.class.getClassLoader().getResourceAsStream("single.properties")); INSTANCE = new Singleton3(pro.getPropertied("info")); }catch(IOExcepption e){ throw new RuntimeException(e); } } private Singleton3 (String info){ this.info = info; } }
4. Unsafe thread (suitable for single thread) - lazy
/* * Slacker type *(1)Constructor privatization *(2)Static variable save *(3)Provide a static method to get the instance object */ public class Singleton4 { private static Singleton4 instance; private Singleton4 (){ } public static Singleton4 getInstance(){ if(instance == null){ //Add Thread.sleep(100); two objects will be instantiated in the case of multithreading. instance = new Singleton4(); } return instance; } }
- Thread safe (for multithreading) - lazy
/* * Slacker type *(1)Constructor privatization *(2)Static variable save *(3)Provide a static method to get the instance object */ public class Singleton5 { private static Singleton5 instance; private Singleton5 (){ } public static Singleton5 getInstance(){ if(instance == null){//First judge whether it is empty, and then lock it. synchronized(Singleton5.class){ //Add Thread.sleep(100); two objects will be instantiated in the case of multithreading. instance = new Singleton5(); } } return instance; } }
- Static inner class form
/* * When the inner class is loaded and initialized, the INSTANCE object is created. * Static inner classes do not automatically initialize with the loading and initialization of outer classes. They are loaded and initialized separately. * It's thread safe because it's created by loading and initializing inner classes. */ public class Singleton6 { private Singleton6 (){ } private static class Inner{ private static final Singleton6 INSTANCE = new Singleton6(); } public static Singleton6 getInstance(){ return Inner.INSTANCE; } }