天天看點

3.[研磨設計模式筆記]單例模式

1.定義

保證一個類僅有一個執行個體,并提供一個通路它的全局通路點。

2.解決問題

——讀取配置檔案的内容

不用模式的解決方案

使用單例模式來解決問題

(餓漢式)

3.模式講解

在不用模式的解決方案中,用戶端是通過new一個AppConfig的執行個體來得到一個操作配置檔案内容的對象。如果在系統運作中,有很多地方都需要使用配置檔案的内容,也就會有很多地方都建立AppConfig對象的執行個體。這樣系統會同時存在多份配置檔案的内容,會嚴重浪費記憶體資源。

解決思路

分析上面的問題,一個類能夠/被建立多個執行個體,問題在于/類的構造方法是公開的,也就是可以/讓類的外部/通過構造方法建立多個執行個體。要控制一個類/隻被建立一個執行個體,那就是把類的構造函數/私有化,然後由這個類來/提供外部通路/類執行個體的方法,這就是單例模式的實作方式。

單例模式使用來保證這個類在運作期間隻會被建立一個類執行個體,另外,單例模式還提供一個全局唯一通路這個類執行個體的通路點,就是getInstance方法。

示例代碼

(懶漢式)

在懶漢式方案裡,強制加上static,并沒有使用static的特性;而在餓漢式方案裡,是主動加上static,使用了static的特性。

單例模式的懶漢式實作展現了延遲加載的思想,即就是一開始不要加載資源或資料,一直等,等到要使用這個資源或資料才加載,也成Lazy Load。

單例模式的懶漢式實作還展現了緩存的思想,即當某些資源或資料被頻繁地使用,而這些資源或資料存儲在系統外部(如資料庫、硬碟檔案等),每次操作這些資料的時候都要去擷取。通過把這些資料緩存到記憶體中,每次操作先到記憶體裡面找,如果有就直接使用,如果沒有就去擷取,并設定到緩存中,下一次通路的時候就可以直接從記憶體中擷取。

應用範圍

Java裡面實作單例的是一個虛拟機範圍,虛拟機在通過自己的ClassLoader裝載餓漢式實作單例類就會建立一個類的執行個體。

單例模式調用示意圖

3.[研磨設計模式筆記]單例模式
3.[研磨設計模式筆記]單例模式

單例模式的優缺點

1.時間和空間

懶漢式是典型的時間換空間;

餓漢式是典型的空間換時間。

2.線程安全

不加同步的懶漢式是線程不安全的;

餓漢式是線程安全的。

雙重檢查加鎖

指的是:并不是每次進入getInstance方法都需要同步,而是先不同步,進入方法後,先檢查執行個體是否存在,如果不存在,就在同步的情況下建立一個執行個體,這是第二重檢查。這樣,就隻需要同步一次,進而減少多次在同步情況下進行判斷浪費的時間。

雙重檢查加鎖的實作使用了一個關鍵字volatile,意思是:被volatile修飾的變量的值,将不會被本地線程緩存,所有對該變量的讀寫都是直接操作共享記憶體的,進而確定多個線程能正确的處理該變量。

4.思考

單例模式的本質:控制執行個體數目

何時選用單例模式:

如果當:需要控制一個類執行個體隻能有一個,且客戶隻能從一個全局通路點控制它時,選用單例模式。

說明:筆記内容摘自《研磨設計模式》陳臣,王斌

關聯:整理了一些Java軟體工程師的基礎知識點

繼續閱讀