單例設計模式

2021-08-15 02:12:32 字數 2666 閱讀 7829

使用單例模式的好處:

(1)對於頻繁使用的物件,可以減輕不停的建立物件所花費的時間。

(2)由於new的次數減少,從而降低了系統記憶體的使用頻率,同時也減輕了gc的壓力,縮短了gc的停頓時間。

餓漢式

public class singleton

public static singleton getinstance()

public static void open()

public static void main(string args)

}

說明:這種單例實現非常簡單有十分可靠,但是它唯一的不足就是無法對instance物件做延遲載入。也就是說在上述**中,當我們執行singleton.open()時,會輸出「建立單例」,「開始」。我們不需要singleton物件,但是在執行open()過程中時會將instance進行例項化。所以我們要延遲載入。

懶漢式

public class singleton

public static synchronized singleton getinstance()

public static void open()

public static void main(string args)

}

說明根據懶漢式,我們可以解決延遲載入的問題。但是由於在懶漢式中會出現多執行緒不友好的問題,所以對getinstance()方法進行了同步處理(餓漢式天生多執行緒友好,故不需要進行處理)。進行同步處理之後,則呼叫該方法耗時就長。無形中就降低了程式的效能。

雙向校驗鎖的形式

public class singleton

public static singleton getinstance()}}

return instance;

} public static void open()

public static void main(string args)

}

說明:這是懶漢式的一種表現形式,該操作不再是對整個函式進行加鎖,只對存在併發問題的部分**進行加鎖。這樣做的好處是改善效能。但是這樣做還是會有一點不安全。

volatile關鍵字的雙向校驗

public class singleton

public static singleton getinstance()}}

return instance;

} public static void open()

public static void main(string args)

}

說明:這種寫法更加強化了執行緒安全性,當宣告instance引用不使用volatile時,可能執行緒a先執行instance = new singleton(),但是new物件這個操作並不是原子性的,在new物件的過程分為三步,按執行順序分別是

1.給物件分配記憶體空間

2.初始化例項物件

3.將引用instance指向分配的記憶體空間

因為處理器會優化這三個步驟,使得這三個步驟發生重排序,執行步驟變為了1->3->2。當執行緒執行完了3時(此時instance引用並不是null,而是指向了1步驟中分配的記憶體位址。但是,instance物件初始化並沒有完成,並不是乙個完整的物件),快要執行2步驟,突然cpu切換了資源,那麼b執行緒就進入該方法當中,instance此時是不等於null的,所以直接執行return。此時返回的是乙個不完整的物件,可能會造成系統的崩潰

靜態內部類的形式

public class singleton

public static void open()

public static singleton getinstance()

private static class singletoninner

public static void main(string args)

}

說明:在這個實現中,單例模式使用內部類的形式來維護單例的例項.當singleton類被載入時,其內部類並不會被初始化,而呼叫getinstance()函式時,就會對其進行初始化.這種實現很好的兼備了上述兩種實現的優點.但是這個實現仍然有例外情況,可能導致系統生成多個例項.如通過反射機制,強行呼叫單例類的構造方法.這種極端的方式就不做討論.除了這些極端的方式會破壞例項的單例性,仍然有一些合法的方式對其單例性進行破壞.如序列化.下面舉個例子

public class singleton implements serializable

public static singleton getinstance()

public static void open()

// private object readresolve()

public static void main(string args) throws exception

}

當注釋部分**沒有寫時,構建測試**先獲取instance物件,再對singleto進行序列化和反序列化得當的物件進行比較,會發現這兩個物件不相等。解決的辦法是寫上注釋部分的**,這樣反序列化過程中readobject()方法就如同虛設,它直接使用readresolve()方法替換了原本的返回值,從而在形式上構造了單例。

單例設計模式(餓漢單例設計模式 懶漢單例設計模式)

1.什麼是單例 單例的意思是乙個類永遠只存在乙個物件,不能建立多個物件。2.為什麼要用單例 開發中有很多的物件我們只需要乙個,例如虛擬機器物件,任務管理器物件 物件越多越佔記憶體,有時候只需要乙個物件就可以實現業務,單例可以節省記憶體空間。3.如何實現單例 單例的實現方式有 餓漢單例設計模式 通過類...

設計模式 單例設計模式

歷史 最早是建築學領域的模式,然後gof四人由其引申到編碼方面,總結了23種設計模式 設計模式 解決某一類事情最行之有效的方法 2.1 體現 餓漢式,保證物件的唯一性 class singleton 私有化建構函式禁止該類建立物件 private static singleton st new si...

設計模式 單例設計模式

單例模式,是一種常用的軟體設計模式。在它的核心結構中只包含乙個被稱為單例的特殊類。通過單例模式可以保證系統中乙個類只有乙個例項。即乙個類只有乙個物件例項 單例模式的要點有三個 一是某個類只能有乙個例項 二是它必須自行建立這個例項 三是它必須自行向整個系統提供這個例項。單例設計模式 解決的問題 可以保...