当前位置:网站首页>Lazy singleton mode from shallow to deep

Lazy singleton mode from shallow to deep

2022-06-25 18:14:00 [email protected]

1. Most basic version , Don't worry about thread safety

package JavaBasis.chapter8;

public class Singleton {
    
    private static Singleton instance=null;
    private Singleton(){
    }// Privatization constructor , Not visible from the outside 
    private static Singleton getInstance()
    {
    
           if(instance==null)// Instance not created 
           instance=new Singleton();

           return instance;// Return to the created instance 
    }
}

2. Problems caused by introducing multithreading

The above code is thread unsafe in a multi-threaded environment , Like threads 1 First, it comes to if Judgment statement here , Found that the instance was not created , So you start creating instances ; When a thread 2 Here we go again , But threads 1 Of instance It's not finished yet , here if Judgment is still satisfied , Then the thread 2 You enter the create statement , Finally, two instace object

  • Solution 1 Put a lock on the whole method
package JavaBasis.chapter8;

public class Singleton {
    
    private static Singleton instance=null;
    private Singleton(){
    }// Privatization constructor , Not visible from the outside 
    private static synchronized Singleton getInstance()
    {
    
           if(instance==null)// Instance not created 
           instance=new Singleton();

           return instance;// Return to the created instance 
    }
}

This solution can solve the thread safety problem , But there is another problem , Because the whole method is locked , Suppose I now have a thread 1 Get the lock and enter the method to create the object , Threads 1 end , After that thread 2 Here comes the entry method to discover that the object has been created , Go straight back to , But if the thread 3 Here we are , Because the whole method is locked , Threads 3 be unable to enter , It must wait for the thread 2 You can't go in until it's over , But it just wants to return an object that has been created , Wasted time , Performance overhead , Then you might come up with the following solution

  • Solution 2 Add... To the creation process synchronized
package JavaBasis.chapter8;

public class Singleton {
    
    private static Singleton instance=null;
    private Singleton(){
    }// Privatization constructor , Not visible from the outside 
    private  static  Singleton getInstance()
    {
           if(instance==null)// Instance not created 
           {
    
           synchronized(Singleton.class)
           {
     instance=new Singleton();
           }
           }

           return instance;// Return to the created instance 
    }
}

The above code also has thread safety problems , Now thread 1 First enter the method and get the lock to start creating the object , In a thread 1 Before the object is created , Threads 2 Also came in , Threads 2 Judge if Found object not created , Then enter the , But you can't get the lock , So I began to wait , Wait until the thread 1 After creating the object and releasing the lock, the thread 2 To create objects again , The reason is that it has been done before if Judge

  • Solution 3 Double check lock
package JavaBasis.chapter8;

public class Singleton {
    
    private static Singleton instance=null;
    private Singleton(){
    }// Privatization constructor , Not visible from the outside 
    private  static  Singleton getInstance()
    {
           if(instance==null)// Instance not created 
           {
    
           synchronized(Singleton.class)
           {
     
           if(instance==null)
           instance=new Singleton();
           }
           }

           return instance;// Return to the created instance 
    }
}

In the scheme 2 The above problems can be solved by adding a judgment to the existing problems , For example, the plan 2 Threads mentioned in 2, Although it passed the first if Judge , When it is when it gets the lock if When judging, it is found that the object has been used by the thread 1 Created , So return the object directly , So far, I don't think it's done , But even a double check lock , There are also some problems

      if(instance==null)// Instance not created 
           {
    
           synchronized(Singleton.class)
           {
     
           if(instance==null)
           instance=new Singleton();//1
           }
           }

Look at this code ,1 The process of creating objects at is divided into the following 3 Step :
1. Allocate memory space for objects
2. Initialize object
3. Give Way instance The reference points to the address of the initialization object
But again Java Instruction rearrangement will occur in , To be specific 2 3 The order of will change , Maybe first 3 Re execution 2, What problems can this lead to
for instance : Threads 1 Enter the synchronization code block and start creating objects , First executed. 1, And then execute 3, performed 3instance No nul 了 ,instance Point to a specific address , The object in this address is not initialized , In a thread 1 It hasn't been implemented yet 2 In operation , Threads 2 Came in , It found the first if sentence ( Or maybe the second if sentence ) Inside instance No null 了 , So directly return instance 了 , However instance Is an uninitialized object
Solution : stay instance prefix volitile keyword , Command rearrangement turns off

原网站

版权声明
本文为[[email protected]]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202190532337408.html