1. Singleton mode
Introduction
Implementation of singleton mode
Hungry Chinese style: class loading will cause the single instance object to be created. When a class is loaded, whether it is used or not, the object will be in memory, which will cause a waste of memory.
Mode 1: static variable mode
package Creator mode.Singleton mode; //Singleton static member variable public class Singleton { //1. Private construction method. The singleton mode allows an object. If the outside world cannot access it, the object cannot be created private Singleton(){} //2. Create this class object in this class and return the object in the static method, so this property needs to be static private static Singleton instance = new Singleton(); //3. Provide a public way to access the object so that the outside world can obtain the object //The outside world cannot create this object, and ordinary methods cannot be called without an object, so the class name should be used Static method name to call the method, so as to obtain the object public static Singleton getInstance(){return instance;}; }
package Creator mode.Singleton mode; public class Client { public static void main(String[] args) { //Create an object of the Singleton class Singleton instance = Singleton.getInstance(); Singleton instance1 = Singleton.getInstance(); //Judge whether the two objects obtained are the same System.out.println(instance == instance1);//Output true } }
Mode 2: static code block mode
package Creator mode.Singleton mode: hungry Chinese static code block mode; public class Singleton { //1. Construction method private Singleton(){}; //2.Singleton object private static Singleton instance; //3. Assign a value to this object static { instance = new Singleton(); } public static Singleton getInstace(){ return instance; } }
package Creator mode.Singleton mode: hungry Chinese static code block mode; public class Client { public static void main(String[] args) { Singleton instance = Singleton.getInstace(); Singleton instance1 = Singleton.getInstace(); //Judge whether to achieve single example System.out.println(instance1 == instance);//true } }
Method 3: enumeration method
Enumeration types are thread safe and can only be loaded once
public enum Singleton { INSTANCE; }
public class Client { public static void main(String[] args) { Singleton instance = Singleton.INSTANCE; Singleton instance1 = Singleton.INSTANCE; System.out.println(instance1 == instance);//true } }
Lazy: class loading does not cause the single instance object to be created, but is created when the object is first used.
Mode 1: thread unsafe
package Creator mode.Singleton mode lazy thread unsafe mode; public class Singleton { private Singleton(){}; //Here, only a variable of type is declared without assignment private static Singleton instance; public static Singleton getInstance(){ /* In this way, threads are not safe. If there are two threads, when thread 1 executes the judgment statement, the next sentence has not been executed at this time. If thread 2 takes resources, Thread 2 is also determined to be null. At this time, when the two threads execute further, they will get objects, which are different. */ if(instance == null){ instance = new Singleton(); } return instance; } }
Mode 2: thread safety
package Creator mode.Singleton mode lazy thread unsafe mode; public class Singleton { private Singleton(){}; //Here, only a variable of type is declared without assignment private static Singleton instance; //The difference from mode 1 is that the keyword synchronized is added public static synchronized Singleton getInstance(){ if(instance == null){ instance = new Singleton(); } return instance; } }
Mode 3: double check lock
For method 2, since the judgment will be false every time after obtaining the object once, you don't need to execute the statement in if every time. No matter which thread is safe when executing return, the thread will be unsafe only when the object is not determined, but every time each thread enters the lock, it will affect the code efficiency, so you need to adjust the lock timing. So there's a double check.
I don't understand the usage of synchronized synchronized parameter and its meaning_ CSDN blog_ synchronized parameter
package Creator mode.Single case mode dual check lock; public class Singleton { private Singleton(){}; private static Singleton instance; public static Singleton getInstance(){ //In the first judgment, if the instance value is not null, there is no need to preempt the lock and return the object directly. if(instance == null){ //The object of the lock is the bytecode object of the current class synchronized (Singleton.class){ //Second judgment if(instance == null){ instance = new Singleton(); } } } return instance; } }
When declaring instance, add volatile after static
Method 4: static internal class method
In the static internal class singleton mode, the instance is created by the internal class. Because the JVM will not load the static internal class during the process of loading the external class, it will be loaded only when the properties / methods of the internal class are called. And initialize its static properties. Because static attributes are modified by static, they are guaranteed to be instantiated only once, and the instantiation order is strictly guaranteed. The attribute of the static inner class is because the attribute can be called without creating an object.
The INSTANCE will not be initialized when the Singleton class is loaded for the first time. Only when getInstance is called for the first time, the virtual machine loads the SingleHolder and initializes the INSTANCE, which can not only ensure thread safety, but also ensure the uniqueness of the Singleton class.
In the class, it is guaranteed that the object will not be created to occupy memory when the method is not called, because the internal class will be loaded when the method is called.
public class Singleton { private Singleton(){ } //Declare static inner classes private static class SingletonHolder{ //Declare and initialize the object. final is to prevent external modification private final static Singleton INSTANCE = new Singleton(); } //Provide public access public static Singleton getInstance(){ return SingletonHolder.INSTANCE; } }
Summary: double check lock and static inner class are recommended for singleton mode. Without considering the waste of space, you can also choose the hungry Chinese enumeration method.
Existing problems
If you want to break the above singleton mode (except enumeration), you can create multiple objects in two ways: serialization and reflection.
Problem solving
Because you haven't learned serialization and reflection yet, leave it empty first
Application of singleton mode in JDK source code
Runtime class