The singleton pattern analyzes code optimization methods

  • 2020-04-01 03:49:37
  • OfStack

The singleton pattern, one of 23 design patterns, is a simpler design pattern that aims to return the same object no matter how many times it is invoked, and is characterized by constructor privatization.

It is divided into two structures, one is lazy, one is hungry, they have advantages and disadvantages, we first from the hungry, the code is as follows:


public class Single { 
  private static Single single = new Single();  
  private Single() {  
  } 
   public Single getInstance() { 
    return single; 
  }  
}

It can be seen from the above program that although we did achieve the purpose of loading the same object, when the program is loaded, it will create the single object. When the class has more than one such method, we may not use most of the singletons in this object, resulting in a waste of memory. So there is a lazy singleton pattern, the code is as follows:


public class Single { 
  private static Single single = null;  
  private Single() {  
  } 
 
  public Single getInstance() { 
    if(single==null){ 
      single = new Single(); 
    } 
    return single; 
  }  
}

This way, the object will only be new when we actually call it, but this is problematic.

When the second code above is called by two threads when it is loaded for the first time, two different objects will be generated, so the thread is not safe. At this time, it will think of adding a lock to this method, and the code after the lock is as follows:


public class Single { 
  private static Single single = null;  
  private Single() {  
  } 
 
  public synchronized Single getInstance() { 
    if (single == null) { 
      single = new Single(); 
    } 
    return single; 
  }  
}

That it really did it thread-safe, but when the lock this method to perform a lot of things inside, call this method the amount of time will be very long, it is fatal to the server, because this method, that is, if a thread has been calling the other thread is no way to adjust, the server is blocked, so the updated code is as follows:


public class Single { 
  priate static Single single = null;  
  private Single() {  
  } 
 
  public Single getInstance() { 
    if (single == null) { 
      synchronized (Single.class) { 
        single = new Single(); 
      } 
    } 
    return single; 
  } 
}

After careful observation found that is not locked, when for the first time for two threads to reach the getInstance () method if judgment, one must have been blocked, when another execution of the block the thread won't determine whether is empty, will create an object, that have more than one object is created, and to upgrade its, the code is as follows:


public class Single { 
  private static Single single = null;  
  private Single() {  
  } 
 
  public Single getInstance() { 
    if (single == null) { 
      synchronized (Single.class) { 
        if (single == null) { 
          single = new Single(); 
        } 
      } 
    } 
    return single; 
  } 
}

This will not cause the above problems, and only lock once, because the second time you execute this method, you will skip the if judgment, return the single, will not be locked again, and the execution will be very efficient.

But even so, there is still a problem, because we can not determine whether to assign the object first or create the object first in memory, so the second program may get the object is half initialized, after jdk1.5, we can use the keyword volatile to avoid this situation, the code is as follows:


public class Single { 
  private static volatile Single single = null;  
  private Single() {  
  } 
 
  public Single getInstance() { 
    if (single == null) { 
      synchronized (Single.class) { 
        if (single == null) { 
          single = new Single(); 
        } 
      } 
    } 
    return single; 
  } 
}

But this situation is rarely used, I'm here just to learn, hee hee


Related articles: