設計模式(1)----單例模式
- 簡介:
- 單例模式(Singleton)是一種常用的軟件設計模式,在它的核心結構中只包含一個被稱為單例的特殊類。
- 定義:
- 確保一個類只有一個實例,而且自行實例化並向整個系統提供這個實例。
- 單例模式
- 單例模式根據實例化對象時機不同分為兩種模式。
- 餓漢式:餓漢式單例在單例類被加載的時候,就實例化一個對象交給自己引用
- 懶漢式:懶漢式單例在調用取得實例方法的時候才會被實例化對象。
代碼如下:
- 單例模式根據實例化對象時機不同分為兩種模式。
package com.lvsling.test; /** * 單例模式 * @author Administrator * */ public class TestSingleton { public static void main(String[] args) {
//驗證ClassA是單例 ClassA a1 = ClassA.newInstance(); ClassA a2 = ClassA.newInstance(); System.out.println(a1 == a2);//true
//驗證ClassB是單例 ClassB b1 = ClassB.newInstance(); ClassB b2 = ClassB.newInstance(); System.out.println(b1 == b2);//true:單例
//驗證ClassC是單例 ClassC c1 = ClassC.newInstance(); ClassC c2 = ClassC.newInstance(); System.out.println(c1 == c2);//true:單例
}
} //餓漢式 class ClassA{ private static ClassA instance = new ClassA(); public static ClassA newInstance(){ return instance; } private ClassA(){
} } //懶漢式 class ClassB{ private static ClassB instance = null; public static synchronized ClassB newInstance(){ if (instance == null) instance= new ClassB(); return instance; } private ClassB(){
} } //靜態內部類:既實現了線程安全,又避免了同步帶來的性能影響。 class ClassC{ private static class Holder{ public static ClassC instance = new ClassC(); } public static ClassC newInstance(){ return Holder.instance; } private ClassC(){
} } |
- 餓漢式和懶漢式的區別
- 從餓漢,懶漢來看:
- 餓漢式的類一旦加載,就把單例初始化完成,餓漢式創建單例是寫在static修飾的靜態屬性後。
- 懶漢式static修飾的靜態屬性創建一個null的空間,當調用newInstance的時候,才回去初始化單例
- 從線程安全的角度:
- 餓漢式天生就是線程安全的
- 懶漢式本身並非線程安全,實現線程安全而采用synchronized鎖標記,或者靜態內部內的方法
- 從性能方面:
- 餓漢式在類創建的同時就實例化一個靜態對象出來,不管之後會不會使用這個單例,都會占用一些內存,但是,如果在第一次調用使用時速度會很快因為它在類加載的時候已經創建好了,單例已經存在了
- 懶漢式因為調用newInstance才會去實例化對象,所以第一次調用時性能會延遲,但是懶漢式不會浪費內存,用到時才會創建單例對象。
- 從餓漢,懶漢來看:
- 單例模式的優點:
- 防止其它對象對自己的實例化,確保所有的對象都訪問一個實例 。
- 提供了對唯一實例的受控訪問。
- 由於在系統內存中只存在一個對象,因此可以 節約系統資源,當 需要頻繁創建和銷毀的對象時單例模式無疑可以提高系統的性能。
- 避免對共享資源的多重占用。
- 單例模式的適用場景:
- 需要頻繁實例化然後銷毀的對象。
- .創建對象時耗時過多或者耗資源過多,但又經常用到的對象。
- 有狀態的工具類對象。
- 頻繁訪問數據庫或文件的對象。
- 總結:
- 我認為,在使用單例模式時,如果不考慮資源的使用,可以采用餓漢式,在使用的時候更快更迅速。
- 如果考慮資源的浪費,可以采用靜態內部內的方式去實現。
- 單例模式其核心思想就是將構造方法私有化,通過靜態方法獲取一個唯一的實例
- 在獲取的過程中,既要保證線程安全,又要防止反序列化導致重新生成實例對象。
設計模式(1)----單例模式