天天看點

設計模式--單例模式

單例設計模式

Singleton是一種建立型模式,指某個類采用Singleton模式,則在這個類被建立後,隻可能産生一個執行個體供外部通路,并且提供一個全局的通路點。

核心知識點如下:

(1) 将采用單例設計模式的類的構造方法私有化(采用private修飾)。

(2) 在其内部産生該類的執行個體化對象,并将其封裝成private static類型。

(3) 定義一個靜态方法傳回該類的執行個體。

設計模式--單例模式

/** 
 * 方法一
 * 單例模式的實作:餓漢式,線程安全 但效率比較低 
 */  
public class SingletonTest {  

    // 定義一個私有的構造方法
    private SingletonTest() {  
    }  

    // 将自身的執行個體對象設定為一個屬性,并加上Static和final修飾符
    private static final SingletonTest instance = new SingletonTest();  

    // 靜态方法傳回該類的執行個體
    public static SingletonTest getInstancei() {  
        return instance;  
    }  
  
}      
設計模式--單例模式

方法一就是傳說的中的餓漢模式

優點是:寫起來比較簡單,而且不存在多線程同步問題,避免了synchronized所造成的性能問題;

缺點是:當類SingletonTest被加載的時候,會初始化static的instance,靜态變量被建立并配置設定記憶體空間,從這以後,這個static的instance對象便一直占着這段記憶體(即便你還沒有用到這個執行個體),當類被解除安裝時,靜态變量被摧毀,并釋放所占有的記憶體,是以在某些特定條件下會耗費記憶體。

設計模式--單例模式
/**  
 *方法二
 * 單例模式的實作:飽漢式,非線程安全   
 *   
 */  
public class SingletonTest {

    // 定義私有構造方法(防止通過 new SingletonTest()去執行個體化)
    private SingletonTest() {   
    }   

    // 定義一個SingletonTest類型的變量(不初始化,注意這裡沒有使用final關鍵字)
    private static SingletonTest instance;   

    // 定義一個靜态的方法(調用時再初始化SingletonTest,但是多線程通路時,可能造成重複初始化問題)
    public static SingletonTest getInstance() {   
        if (instance == null)   
            instance = new SingletonTest();   
        return instance;   
    }   
}       
設計模式--單例模式

方法二就是傳說的中的飽漢模式

優點是:寫起來比較簡單,當類SingletonTest被加載的時候,靜态變量static的instance未被建立并配置設定記憶體空間,當getInstance方法第一次被調用時,初始化instance變量,并配置設定記憶體,是以在某些特定條件下會節約了記憶體;

缺點是:并發環境下很可能出現多個SingletonTest執行個體。

設計模式--單例模式
/**  
 *方法三
 * 單例模式的實作:飽漢式,線程安全簡單實作   
 *   
 */  
public class SingletonTest {

    // 定義私有構造方法(防止通過 new SingletonTest()去執行個體化)
    private SingletonTest() {   
    }   

    // 定義一個SingletonTest類型的變量(不初始化,注意這裡沒有使用final關鍵字)
    private static SingletonTest instance;   

    // 定義一個靜态的方法(調用時再初始化SingletonTest,使用synchronized 避免多線程通路時,可能造成重的複初始化問題)
    public static synchronized  SingletonTest getInstance() {   
        if (instance == null)   
            instance = new SingletonTest();   
        return instance;   
    }   
}       
設計模式--單例模式

方法三為方法二的簡單優化

優點是:使用synchronized關鍵字避免多線程通路時,出現多個SingletonTest執行個體。

缺點是:同步方法頻繁調用時,效率略低。

設計模式--單例模式
/**  
 * 方法四
 * 單例模式最優方案
 * 線程安全  并且效率高  
 *  
 */  
public class SingletonTest { 

    // 定義一個私有構造方法
    private SingletonTest() { 
     
    }   
    //定義一個靜态私有變量(不初始化,不使用final關鍵字,使用volatile保證了多線程通路時instance變量的可見性,避免了instance初始化時其他變量屬性還沒指派完時,被另外線程調用)
    private static volatile SingletonTest instance;  

    //定義一個共有的靜态方法,傳回該類型執行個體
    public static SingletonTest getIstance() { 
        // 對象執行個體化時與否判斷(不使用同步代碼塊,instance不等于null時,直接傳回對象,提高運作效率)
        if (instance == null) {
            //同步代碼塊(對象未初始化時,使用同步代碼塊,保證多線程通路時對象在第一次建立後,不再重複被建立)
            synchronized (SingletonTest.class) {
                //未初始化,則初始instance變量
                if (instance == null) {
                    instance = new SingletonTest();   
                }   
            }   
        }   
        return instance;   
    }   
}      
設計模式--單例模式

方法四為單例模式的最佳實作。記憶體占用地,效率高,線程安全,多線程操作原子性。