1. 程式人生 > >JAVA基礎——設計模式之單列模式

JAVA基礎——設計模式之單列模式

因此 style 對象 lba 原子 類型 div 等於 加載

一:單例設計模式

Singleton是一種創建型模式,指某個類采用Singleton模式,則在這個類被創建後,只可能產生一個實例供外部訪問,並且提供一個全局的訪問點

單例設計模式的特點:

  1. 單例類只能有一個實例
  2. 單例必須創建對象
  3. 單例類需要對外提供該對象

核心知識點如下

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

  2. 在其內部產生該類的實例化對象,並將其封裝成private static類型。
  3. 定義一個靜態方法返回該類的實例。


二:單例式的分類

1.餓漢模式:

優點是:

  1. 寫起來比較簡單,
  2. 而且不存在多線程同步問題,
  3. 避免了synchronized所造成的性能問題;

缺點是:

  1. 當類被加載的時候,會初始化static的instance
  2. 靜態變量被創建並分配內存空間,從這以後,這個static的instance對象便一直占著這段內存(即便你還沒有用到這個實例),
  3. 當類被卸載時,靜態變量被摧毀,並釋放所占有的內存,因此在某些特定條件下會耗費內存。

技術分享圖片
/** 
 * 方法一
 * 單例模式的實現:餓漢式,線程安全 但效率比較低 
 */  
public class SingletonTest {   
    // 定義一個私有的構造方法
    private SingletonTest() {  
    }   
    // 將自身的實例對象設置為一個屬性,並加上Static和final修飾符
    private static final SingletonTest instance = new SingletonTest();   
    // 靜態方法返回該類的實例
    public static SingletonTest getInstancei() {  
        return instance;  
    }  
  
}
技術分享圖片


2.飽漢式(懶漢式)

優點是

  1. 寫起來比較簡單,
  2. 當類被加載的時候,靜態變量static的instance未被創建並分配內存空間
  3. 當getInstance方法第一次被調用時,初始化instance變量,並分配內存,因此在某些特定條件下會節約了內存

缺點是

  1. 並發環境下很可能出現多個SingletonTest實例。

技術分享圖片
/**  
 *方法二
 * 單例模式的實現:飽漢式,非線程安全   
 *   
 */  
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; } }
技術分享圖片

3.方法二的簡單優化版

優點是:使用(同步鎖)synchronized關鍵字避免多線程訪問時,出現多個類的實例。 缺點是:同步方法頻繁調用時,效率略低。

技術分享圖片
/**  
 *方法三
 * 單例模式的實現:飽漢式,線程安全簡單實現   
 *   
 */  
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;   
    }   
} 
技術分享圖片

4單例模式的最佳實現

  1. 內存占用地
  2. 效率高
  3. 線程安全
  4. 多線程操作原子性。

技術分享圖片
/**  
 * 方法四
 * 單例模式最優方案
 * 線程安全  並且效率高  
 *  
 */  
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;   
    }   
}
技術分享圖片

(事實上,可以通過Java反射機制來實例化private類型的構造方法,此時基本上會使所有的Java單例實現失效。本帖不討論反射情況下問題,默認無反射,也是常見的面試已經應用場景)

JAVA基礎——設計模式之單列模式