[Turn] thread-safe singleton

Interview, often asked this question: Would you please write a singleton (Singleton Pattern) it. Well, write to write, this is not easy. Write a smoothly:

  1. public final class EagerSingleton  
  2. {  
  3.     private static EagerSingleton singObj = new EagerSingleton();  
  4.   
  5.     private EagerSingleton(){  
  6.     }  
  7.   
  8.     public static EagerSingleton getSingleInstance(){  
  9.        return singObj;
  10.     }  
  11. }  
    The wording of the so-called starvation mode, each object in the absence of use has been initialized. This may bring potential performance problem: If the object is very high? Before this object is not used, put it loaded into memory to be a huge waste. In view of this situation, we can improve on the above code, using a new design idea - delay loading (Lazy-load Singleton).
  1. public final class LazySingleton  
  2. {  
  3.     private static LazySingleton singObj = null;  
  4.   
  5.     private LazySingleton(){  
  6.     }  
  7.   
  8.     public static LazySingleton getSingleInstance(){  
  9.         if (null == singObj) singObj LazySingleton = new ();
  10.           return singObj;
  11.     }  
  12. }  
    The wording of the so-called lazy mode. It uses lazy loading to ensure that the object is not used before, is not initialized. Generally, however, this time the new interviewer will ask questions to make things difficult for it. He will ask: The wording thread safe? The answer must be: safe. This is because a plurality of threads may run simultaneously to the ninth line is determined singObj is null, then simultaneously initialized. So, this is a problem is how to make this code is thread safe? Very simple, plus a Synchronized in front of that method on OK.
  1. public final class ThreadSafeSingleton  
  2. {  
  3.     private static ThreadSafeSingleton singObj = null;  
  4.   
  5.     private ThreadSafeSingleton(){  
  6.     }  
  7.   
  8.     public static Synchronized ThreadSafeSingleton getSingleInstance(){  
  9.         if (null == singObj) singObj ThreadSafeSingleton = new ();
  10.             return singObj;
  11.     }  
  12. }  
    I write to you, the interviewer may still be cunning looked at you and continue to make things difficult: this writing there is no performance problem? The answer is definitely yes!  The price is bound to a certain degree of synchronization of the concurrent degree program reduced . Is there any way to, on the one hand is thread-safe, there may be a high degree of concurrency it? We observed that the reason is in fact not thread-safe initialization of an object when it is possible to think of ways to reduce the size of synchronization, synchronize only when the object is initialized. Here it is necessary to propose a new design ideas - double-checked locking (Double-Checked Lock).
  1. public final class DoubleCheckedSingleton  
  2. {  
  3.     private static DoubleCheckedSingletonsingObj = null;  
  4.   
  5.     private DoubleCheckedSingleton(){  
  6.     }  
  7.   
  8.     public static DoubleCheckedSingleton getSingleInstance(){  
  9.         if(null == singObj ) {
  10.               Synchronized(DoubleCheckedSingleton.class){
  11.                      if(null == singObj)
  12.                            singObj = new DoubleCheckedSingleton();
  13.               }
  14.          }
  15.        return singObj;
  16.     }  
  17. }  
     The wording such that only the new load objects are synchronized after finished loading, the ninth row in the other threads can determine the cost of the lock skip line 15 directly to the code. Do a very good degree of concurrency.
     Thus, the above wording on the one hand to achieve a Lazy-Load, another has also done a good degree of concurrency thread-safe, everything was perfect fancy. This is, the interviewer might be your answer satisfied nod. But you say made at this time, in fact, such an approach is still a problem! ! Where is the problem? A thread is assumed to perform the line 9, it is judged object is empty, then the thread A executed to line 12 to initialize the object, but initialization takes time, but the address of the object in fact already exists. Thread B is also performed at this time to the ninth row, it is determined not empty, then jump directly to the line 15 to obtain this object. However, this object has  not been fully initialized! I did not get a fully initialized object what's the use! ! Discussion of the Double-Checked Lock There are many, it is now recognized as a Anti-Pattern, not recommended! So when you hear your interviewer This statement of reply, he would not be Hold live it?
     So is there any better written it? Have! Here again propose a new model -. Initialization on Demand Holder This method uses an internal class to do delay loading the object, in this inner class initialization time, JLS (Java Language Sepcification) will ensure that this class thread-safe . The wording of the greatest beauty is that full use of the mechanisms of the Java virtual machine to synchronize guarantee, not a synchronized keyword.
  1. public class Singleton    
  2. {    
  3.     private static class SingletonHolder    
  4.     {    
  5.         public final static Singleton instance = new Singleton();    
  6.     }    
  7.    
  8.     public static Singleton getInstance()    
  9.     {    
  10.         return SingletonHolder.instance;    
  11.     }    
  12. }  
 
At this point, it finished. Provides links For your reference:

Guess you like

Origin www.cnblogs.com/yyy1234/p/12030145.html