1. 程式人生 > >設計模式(五)—— 單例模式

設計模式(五)—— 單例模式

一、含義

在一個系統中,確保一個類只有一個例項,並提供一個全域性訪問點,這個類在系統中是獨一無二的。

二、要點

1.單例模式確保程式中最多隻有一個這個類的例項。

2.在java中實現單例模式需要把構造器私有化,並提供一個靜態方法和靜態變數。

三、分析單例模式

首先來看一下最經典的單例模式的程式碼如下:

public class Singleton {

    //利用一個靜態變數來儲存Singleton類的唯一例項
    private static Singleton instance;
    
    
    //將構造器私有化
    private Singleton() {

    }
    
    //使用這個方法來例項物件,並對外提供訪問
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

上訴方法,就是單例模式的懶漢式,也就是說當沒有外部方法呼叫這個類的getInstance()方法事,這個類事不會被例項化的,只有在呼叫這個方法後,這個類才會被例項化。

上訴單例模式,在多執行緒中可能會例項化類,因為在多執行緒中,可能會有多個執行緒進入if條件的判斷,這個時候,就會例項化多個物件,解決這個問題,就是需要將這個方法進行同步處理,每次最多隻能有一個執行緒進入,修改後的程式碼如下:

  //使用這個方法來例項物件,並對外提供訪問,加上synchronized,進行同步處理
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

但是將整個方法進行同步之後,那麼帶來的問題就是會影響程式的效能,因為單例模式是進行一次例項化的操作,所以只是在第一次呼叫的時候,需要進入if的條件,一旦例項化後,就不會在進入if的判斷條件,那麼就可以使用單例模式的另一種寫法,就是餓漢式,就是不管這個物件有沒有在程式其它地方呼叫,上來就直接例項化這個類。

public class Singleton {

    //利用一個靜態變數來儲存Singleton類的唯一例項
    private static Singleton instance = new Singleton();


    //將構造器私有化
    private Singleton() {

    }

    //使用這個方法來例項物件,並對外提供訪問
    public static synchronized Singleton getInstance() {
        
        return instance;
    }
}

還有一個方式就是,我們只需在這個物件第一次進行建立的時候進行同步,保證物件只被建立一次即可,當物件建立後,就不需要再進行同步,那麼我們就可以把同步的範圍進行縮小。

public class Singleton {

    //利用一個靜態變數來儲存Singleton類的唯一例項
    private volatile static Singleton instance;


    //將構造器私有化
    private Singleton() {

    }

    //使用這個方法來例項物件,並對外提供訪問
    public static  Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

文章內容參考《Head First 設計模式》