單例模式使用的前提:
單例模式簡單易用,但是也是所有設計模式中最容易濫用的模式。當你的類想得到很好的擴展時,不能使用單例模式
作用:
首先要說明的是,在一些情況下使用單例模式是可以達到節省資源的目的,但是單例模式的意圖不只是爲了節省資源。如.
果僅僅爲了節省資源就使用單例模式的話可能造成單例模式的濫用。
2)單例模式是爲了確保在整個應用期間只有一個實例,以達到用戶的特定的使用目的
類型:單例模式分爲餓漢式 和 懶漢式 兩中
單例模式弊端:
1)擴展困難,由於GetInstance靜態函數沒有辦法生成子類的實例。如果要拓展,只有重寫那個類。
2)隱式使用引起類結構不清晰。比如有時候,你並不知道某個類A是單例類,當你讀類B的時候,你可能先看它頭文件,
或者類視圖裏的內容,從這裏你無法知道A和B 關係,因爲B類在實現的時候才使用A類的那個所謂的GetInstance函數,
讀不到這行,你就會知道B類對A類的依賴關係。
3)導致程序內存泄露的問題。很多人只是調用了GetInstance生成唯一的實例,卻永遠new被封裝在GetInstance裏忘了去釋放內存。
創造方法:
1.餓漢式
1)創建具有本類返回類型的靜態私有對象,並手動初始化
2)創建私有的構造函數;
3)構造公共的靜態方法(該方法返回類型是本類類型),返回實例化的對象
優點:
餓漢式每次調用的時候不用做創建,直接返回已經創建好的實例
弊端:
當類被加載的時候,該類就對靜態的類對象進行了初始化,從此對象一直存在內存,這樣當對
象未被調用時,實例就一直處於閒置狀態,這樣造成了資源了的浪費,內存佔用比較嚴重
public class DoMain{
public static void main(String[] args){
HungerSingleton hg=HungerSingleton.getInstance();
}
}
class HungerSingleton{
public String name;
private static HungerSingleton instance=new HungerSingleton();
private HungerSingleton(){}
public static HungerSingleton getInstance(){
return instance;
}
}
2.懶漢式
1)創建具有本類返回類型的靜態私有對象,不會手動初始化
2)創建私有的構造函數;
3)構造公共的靜態方法(該方法返回類型是本類類型),
如果對象已經創建,返回實例化的對象
如果對象不存在,怎創建對象並返回
優點:
對象只有在被調用時才進行初始化,不被使用時候是不會初始化的,這樣節省了內存空間
弊端:
在併發的情況下,懶漢式是不安全的。如果兩個線程,我們稱它們爲線程1和線程2,在同一時間調
用getInstance()方法,如果線程1先進入if塊,然後線程2進行控制,那麼就會有兩個實例被創建。
public class DoMain{
public static void main(String[] args){
lazySingleton lg=lazySingleton.getInstance();
}
}
class LazySingleton{
public String name;
private static LazySingleton instance=null;
private LazySingleton(){}
public static getInstance(){
if(instance==null){
instance = new LazySingleton();
}
return instance;
}
}
難點解釋:
private static HungerSingleton instance
1.爲什麼使用private
這裏是用來控制訪問權限的,防止在外部對內的 instance 進行隨意的賦值 :例如:HungerSingleton.instance=null;
2.爲什麼使用static
實現在加載類的時候就對對象加載,也是爲了在靜態方法public static HungerSingleton getInstance(){}可以使用