設計模式-1單例設計模式

單例設計模式

1.餓漢式(靜態常量)(可用)

  1. 構造器私有化
  2. 類的內部建立對象
  3. 向外暴露一個靜態的公共方法
class Singleton{
    //使用private防止new
    private Singleton(){
       
    }
    //類的內部建立對象
    private final static Singleton instance = new Singleton();
    //向外暴露一個靜態的公共方法
    public static Singleton getInstance(){
        return instance;
    }
}

優缺點:java

優勢 寫法簡單,在類裝載的時候完成實例化,避免了線程同步問題
缺點 在類裝載的時候就完成實例化,沒有達到lazy Loading的效果,若是一直沒有用到,會形成內存的浪費

沒法保證是本身觸發的靜態的方法數據庫

2.餓漢式(靜態代碼塊)(可用)

class Singleton{
    //使用private防止new
    private Singleton(){
       
    }
    //類的內部建立對象
    private static Singleton instance;
    
    static{ //在靜態代碼塊裏建立
        instance = new Singleton();
    }
    
    //向外暴露一個靜態的公共方法
    public static Singleton getInstance(){
        return instance;
    }
}

優缺點和靜態常量同樣設計模式

3.懶漢式(線程不安全)

class Singleton{
    //類的內部建立對象
    private static Singleton instance;
    //使用private防止new
    private Singleton(){

    }

    //使用的時候才建立出來 懶漢式
    public static Singleton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}
優勢 起到了lazy Loading的效果
缺點 只能在單線程下使用,在多線程下,一個線程進入了if語句中,沒來得及執行完,另外一個線程也經過了這個判斷語句,這時候就會產生多個實例,因此在多線程下不能夠使用和這個方式

4.懶漢式(線程安全,同步方法)

class Singleton{
    //類的內部建立對象
    private static Singleton instance;
    //使用private防止new
    private Singleton(){ }

    //加入了同步代碼,解決線程不安全問題
    public static synchronized Singleton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}
優勢 解決了線程不安全的問題
缺點 效率很低,方法只須要執行一次就能夠了,可是使用這個方法須要執行不少次,都要進行同步

5.懶漢式(線程安全,同步代碼塊)

class Singleton{
    //類的內部建立對象
    private static Singleton instance;
    //使用private防止new
    private Singleton(){ }

    public static Singleton getInstance(){
        if(instance == null){
            synchronized (Singleton.class){
                 instance = new Singleton();
            }
        }
        return instance;
    }
}

線程不安全(有人寫)不能夠啓到線程同步的做用(==錯誤==)安全

6.雙重檢查(推薦使用)

class Singleton{
    //volatile防止指令重排
    private static volatile Singleton instance;
    //使用private防止new
    private Singleton(){ }

    //雙重檢查,解決線程安全問題,實現了懶加載的方式
    public static Singleton getInstance(){
        if(instance == null){
            synchronized (Singleton.class){
                if(instance == null){
                     instance = new Singleton();
                }
            }
        }
        return instance;
    }
}
優勢 Double-Check多線程中常常使用,保證了線程的安全,避免重複的方法同步,延遲加載,效率較高
結論 推薦使用

7.靜態內部類(推薦使用)

class Singleton{
   
    //使用private防止new
    private Singleton(){ }

    //雙重檢查,解決線程安全問題,實現了懶加載的方式
    public static SingletonInstance{
       private static final Stingleton INSTANCE = new Singleton();
    }
    public static Singleton getInstance(){
       return SingletonInstance.INSTANCE;
    }
}

實現了線程安全,使用延遲加載(很好的一種模式),效率高session

靜態內部類裝載的時候是安全的多線程

8.枚舉(推薦使用)

enum Singleton{
    INSTANCE;
    public void say(){
        System.out.println("ok");
    }
}

藉助JDK1.5的枚舉來實現,避免多線程同步問題,還能防止反序列化從新建立新的對象app

是Josh Bloch提倡的方式工具

9.單例模式在Runtime使用

🌰Runtime:性能

public class Runtime {
    private static Runtime currentRuntime = new Runtime();

    /**
     * Returns the runtime object associated with the current Java application.
     * Most of the methods of class <code>Runtime</code> are instance
     * methods and must be invoked with respect to the current runtime object.
     *
     * @return  the <code>Runtime</code> object associated with the current
     *          Java application.
     */
    public static Runtime getRuntime() {
        return currentRuntime;
    }

    /** Don't let anyone else instantiate this class */
    private Runtime() {}

10.單例模式注意事項

  • 單例模式保證了系統內存中該類只存在一個對象,節省了系統資源,對於一些須要頻繁建立銷燬的對象,使用單例模式能夠提升系統性能
  • 當想實例化一個單例類的時候,必需要記住使用相應的獲取對象的方法,而不是用new
  • 單例模式使用的場景:
    • 須要頻繁的進行建立和銷燬的對象
    • 建立對象時耗時過多或耗費資源過多(重量級對象)但又常常使用到的對象、工具類對象、頻繁訪問數據庫或文件的對象(好比數據源、session工廠)
相關文章
相關標籤/搜索