單例模式6種實現及利弊分析

單例模式6種實現及利弊分析

單例模式三要素

  • 私有的構造方法;
  • 指向自己實例的私有靜態引用;
  • 以自己實例為返回值的靜態的公有方法

1.餓漢式

public class Singleton {
    private static Singleton singleton = new Singleton();

    private Singleton(){};
    
    public static Singleton getSingleton(){
        return singleton;
    }
}

優點:執行緒安全,在類載入完成時就完成了初始化,調用效率高

缺點:類載入較慢,無法達到懶載入的效果

2.懶漢式(非執行緒安全)

public class Singleton{
	private static Singleton singleton;
    
    private Singleton(){};
    
    public static Singleton getSingleton(){
		if(singleton == null){
            singleton = new Singleton();
        }
    	return singleton;
    }
}

優點:節約資源,實現懶載入

缺點:非執行緒安全,獲取對象需要實例化,調用效率低

3.懶漢式(synchronized)

public class Singleton{
	private static Singleton singleton;
    
    private Singleton(){};
    
    //	1.synchronized塊 實現執行緒安全
    /*public static Singleton getSingleton(){
        synchronized(Singleton.class){
        	if(singleton == null){
                singleton = new Singleton();
            }
            return singleton;
        }       
    }
    */
    
    //	2.synchronized方法 實現執行緒安全
    public static synchronized Singleton getSingleton(){
		if(singleton == null){
            singleton = new Singleton();
        }
    	return singleton;
    }
}

優點:執行緒安全,實現懶載入

缺點:獲取對象需要實例化,調用效率低

4.懶漢式(靜態內部類)

public class Singleton{
    private static class Holder{
        private static Singleton singleton = new Singleton();
    }
    
	private Singleton(){};
    
    public static Singleton getSingleton(){
        return Holder.singleton;
    }
}

優點:執行緒安全,實現懶載入

缺點:暫無

5.懶漢式(雙重鎖DCL)

public class Singleton{
    //volatile禁止指令重排序,避免DCL失效問題
    private static volatile Singleton singleton;
    
    private Singleton(){};
    
    public static Singleton getSingleton(){
        //避免重複的同步
        if(singleton == null){
            //如果未實例化,才進行加鎖
            synchronized(Singleton.class){
                if(singleton == null){
					singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

優點:執行緒安全,實現懶載入

缺點:暫無

6.懶漢式(ThreadLocal)

public class Singleton {
    private static volatile Singleton singleton;
    private static ThreadLocal<Singleton> threadLocal = new ThreadLocal<>();

    private Singleton(){};

    public static void createSingleton(){
        synchronized (Singleton.class){
            if (singleton == null){
                singleton = new Singleton();
            }
        }
        threadLocal.set(singleton);
    }

    public static Singleton getSingleton(){
        if(threadLocal.get() == null){
            createSingleton();
        }
        return singleton;
    }
}

優點:也相當於實現了雙重檢查,執行緒安全

缺點:效率不及傳統雙重檢查