DCL: double check lock, as shown below
public class Singleton {
private static volatile Singleton INSTANCE = null;
private Singleton(a){}
public static Singleton getInstance(a){
if(INSTANCE==null) {// First check
synchronized (Singleton.class){
if(INSTANCE==null) {// Second check
INSTANCE = newSingleton(); }}}returnINSTANCE; }}Copy the code
Why to add two empty, the first empty can not add?
Efficiency problem: Assuming that null is not added for the first time, the following synchronized code block will be executed every time the method is entered, whether INSTANCE is null or not. There will be lock competition in multithreading, and the subsequent ones will not be null except for the first initialization, so the efficiency of null detection is higher than that of locking.
Why a second short call?
Prevent multiple initialization: In multithreading, it is possible that two threads have passed the previous first check and come to synchronized. If null is not declared, a thread will create a new Singleton and release the lock. The second thread will create a new Singleton and release the lock.
Can volatile not be added?
The role of volatile:
-
Keep memory visible
-
INSTANCE = new Singleton(); This line mainly does the following things:
-
Make space in memory
-
Execute the constructor to initialize the object
-
Assigning a reference to an object to the INSTANCE variable without volatile is possible at steps 2 and 3, where the order of execution changes to 1, 3, and 2. If I get to step 3, but not step 2, another thread calls the method, You get objects that haven’t been initialized yet. In the above code, the initialization function doesn’t do anything, so it doesn’t matter. But if you need to do something in the initialization function, it matters.
See here, scan the code click follow, continue to get the latest articles