1. 程式人生 > 其它 >自學MYSQL第30天!

自學MYSQL第30天!

單例模式(建立型模式)

基本介紹

單例模式指在整個應用中,某個類只存在一個例項物件,且該類只提供一個取得其物件例項的方法。

應用

JDK的Runtime中使用到了餓漢式單例模式

單例模式的八種方式

(1)餓漢式(靜態常量)

(2)餓漢式(靜態程式碼塊)

(3)懶漢式(執行緒不安全)

(4)懶漢式(執行緒安全,同步方法)

(5)懶漢式(執行緒安全,同步程式碼塊)

(6)雙重檢查

(7)靜態內部類

(8)列舉

餓漢式(靜態常量)(可以使用)

程式碼實現

//餓漢式(靜態常量)
public class Hunger {
     private Hunger(){

     }
     private static final Hunger instance=new Hunger();
     public static Hunger getInstance(){
         return instance;
     }

}

優缺點

  1. 優點:寫法簡單,類載入時完成了例項化,避免了執行緒同步問題。

  2. 缺點:類載入時完成了例項化,沒達到lazy loading(惰性載入)的效果,若從不會用到這個例項會造成記憶體浪費。

    原因:不一定是通過呼叫getInstance()方法導致類載入,有可能是其他的方式導致類載入

  3. 總結:這種單例模式可用,可能造成記憶體浪費。

餓漢式(靜態程式碼塊)(可以使用)

程式碼實現

//餓漢式(靜態程式碼塊)
public class Hunger {
     private Hunger(){

     }
     private static Hunger instance;
     static {
          instance=new Hunger();
     }
     public static Hunger getInstance(){
         return instance;
     }

}

優缺點

同上述靜態屬性的優缺點

懶漢式(執行緒不安全)

程式碼實現

public class Lazy {
    private Lazy(){

    }
    private static Lazy instance;

    public static Lazy getInstance() {
        if(instance==null){
            instance=new Lazy();
        }
        return instance;
    }
}

優缺點

  1. 優點:起到了lazy loading的效果,但只能在單執行緒下使用,
  2. 缺點:在多執行緒下可能產生多個例項,多執行緒不安全
  3. 結論:實際開發中不建議使用。

懶漢式(執行緒安全,同步方法)

程式碼實現

//懶漢式(執行緒安全)
public class Lazy {
    private Lazy(){

    }
    private static Lazy instance;
    //加入同步處理程式碼,解決執行緒不安全問題
    public static synchronized Lazy getInstance() {
        if(instance==null){
            instance=new Lazy();
        }
        return instance;
    }
}

優缺點

  1. 優點:解決了執行緒不安全問題
  2. 缺點:效率低,每個執行緒想要獲得類的例項時,執行getInstance()方法都要進行同步,
  3. 實際開發時不推薦使用

懶漢式(執行緒安全,同步程式碼塊)

程式碼實現

//懶漢式(執行緒安全)
public class Lazy {
    private Lazy(){

    }
    private static Lazy instance;
    public static Lazy getInstance() {
        if(instance==null){
            //此處加入了同步程式碼塊,當兩執行緒都進入了判斷語句,還是有可能造成兩個例項的產生。
           synchronized (Lazy.class){
               instance=new Lazy();
           }
        }
        return instance;
    }
}

優缺點

  1. 這種方法本意是對懶漢式同步方法的改進,因為懶漢式同步方法的效率太低。將其更改為同步產生例項的程式碼塊
  2. 但這種同步方法並不能起到執行緒同步的作用,只要兩個執行緒都進入了判斷語句,還是有可能產生多個例項。
  3. 實際開發中不使用。

雙重檢查(推薦使用)

程式碼實現

//雙重檢測(執行緒安全)
public class Lazy {
    private Lazy(){

    }
    //volatile:保證了一致性,不保證原則性,防止指令重拍
    private volatile static Lazy instance;
    public static Lazy getInstance() {
        if(instance==null){
            //加入同步程式碼塊
           synchronized (Lazy.class){
               //進行第二次檢測
               if(instance==null){
                   instance=new Lazy();
               }
           }
        }
        return instance;
    }
}

優缺點

  1. Double-Check概念是多執行緒開發中經常使用的,進行了兩次if(instance==null)檢查,保證了執行緒安全。
  2. 這樣的設計使得例項化程式碼只執行一次:後面的·1訪問都是直接return例項化物件,避免反覆進行方法同步。
  3. 優點:執行緒安全,延遲載入,效率較高,
  4. 結論:實際開發中建議使用。

靜態內部類(推薦使用)

程式碼實現

//靜態內部類(執行緒安全)
public class Lazy {
    private Lazy(){

    }
    public static Lazy getInstance(){
        return inner.INSTANCE;
    }
    static class inner{
       private static final Lazy INSTANCE=new Lazy();
    }
}

優缺點

  1. 採用了類裝載的機制保證了初始化例項時,只有一個執行緒。
  2. 靜態內部類方法在此類被載入時不會立即例項化,只有在呼叫getInstance()方法時才會載入其內部類並完成此類的例項化。
  3. 類的靜態屬性只會在第一次載入類時初始化,此處,JVM幫助我們保證了執行緒的安全性。類初始化時,別的執行緒無法進入。
  4. 優點:避免了執行緒不安全,使用靜態內部類的特點實現了延遲載入,效率高。
  5. 結論:推薦使用。

列舉(推薦使用)

程式碼實現

public enum Singleton {
    INSTANCE;//屬性
    public void sayOk(){
        System.out.println("ok~~");
    }
}

優缺點

  1. 優點:借用列舉來實現單例模式,不僅能避免多執行緒同步問題,而且可以防止反序列化重新建立新的物件。
  2. 結論:推薦使用

注意事項

  1. 單例模式保證了系統記憶體中該類只存在一個物件,節省了系統資源,對於一些需要頻繁建立銷燬的物件,使用單例模式可以提高系統性能。
  2. 要例項化一個單例類時,使用相應獲取物件的方法而不是new();
  3. 單例模式使用場景:需要頻繁進行建立或銷燬的物件;建立物件時耗時過多或耗費資源過多(重量級物件)且經常使用的物件,工具類物件,頻繁訪問資料庫或檔案的物件(如:資料來源,session工廠等 )