單例模式的定義 定義: 確保某一個類只有一個實例,而且自行實例化並向整個系統提供這個實例. 單例模式的通用類圖如下: 單例模式的優缺點 單例模式的優點: 單例模式的缺點: 單例模式的註意事項 1.高併發情況下,註意線程同步問題 這是一個線程不安全的單例 該單例模式在低併發的情況下可能不會出現問題,若 ...
單例模式的定義
定義: 確保某一個類只有一個實例,而且自行實例化並向整個系統提供這個實例.
單例模式的通用類圖如下:
單例模式的優缺點
單例模式的優點:
- 由於單例模式在記憶體中只有一個實例,減少了記憶體開支,特別是一個對象需要頻繁的創建、銷毀時,而且創建和銷毀時性能又無法優化,單例模式的優勢就非常明顯
- 由於單例模式只生成一個實例,所以減少了系統的性能開銷,當一個對象的產生需要比較多的資源時,如讀取配置、產生其他依賴對象時,則可以通過在應用啟動時直接產生一個單例對象,然後用永久駐留記憶體的方式來解決(在Java EE中採用單例模式時需要註意JVM垃圾回收機制)
- 單例模式可以避免對資源的多重占用,例如一個寫文件動作,由於只有一個實例存在記憶體中,避免對同一個資源文件的同時寫操作
- 單例模式可以在系統設置全局的訪問點,優化和共用資源訪問,例如可以設計一個單例類,負責所有數據表的映射關係
單例模式的缺點:
- 單例模式一般沒有介面,擴展很困難,若要擴展,出來修改代碼基本上沒有第二種途徑可以實現.
- 單例模式對測試是不利的.在並行開發環境中,如果單例模式沒有完成,是不能進行測試的,沒有介面也不能使用mock的方式虛擬一個對象
- 單例模式與單一職責原則有衝突. 一個類應該只實現一個邏輯,而不關心它是否是單例的,是不是要單例取決於環境,單例模式把"要單例"和業務邏輯融合在一個類中.
單例模式的註意事項
1.高併發情況下,註意線程同步問題
這是一個線程不安全的單例
該單例模式在低併發的情況下可能不會出現問題,若併發量增加就可能在記憶體中出現多個實例,破壞了最初的預期.
解決線程不安全的方法有很多,可以在 getInstance 方法前加 synchronized 關鍵字,也可以在方法內增加 synchronized實現,這種被稱為懶漢式單例,還有一種餓漢式單例,代碼如下:
2.對象被覆制的情況
在Java中,對象預設是不可以被覆制的,若實現了Cloneable介面,並實現了clone方法,則可以直接通過對象複製方式創建一個新對象,對象複製是不用調用類的構造函數的,因此即使是私有的構造函數,對象仍然可以被覆制. 一般情況下,類複製的情況是不用考慮的,很少會出現一個單例類會主動要求被覆制的情況,解決該問題的最好方法就是單例類不要實現Cloneable介面
單例模式是23個模式中比較簡單的模式,應用也很廣泛,如在Spring中,每個Bean預設就是單例的,這樣做的優點是Spring容器可以管理這些Bean的生命期,決定什麼時候創建出來,什麼時候銷毀,銷毀的時候要如何處理,等等.