Singleton Pattern : 確保一個類別只有一個實體,並給它一個存取的全域點(global point)

 

把某個類別設計成自己管理的一個Singleton instance,同時也避免其他類別再產生自己的instance

想取得Singleton instance,透過Singleton class是唯一的途徑

 

singleton  

▲Singleton class diagram

uniqueInstance 資料成員紀錄了唯一的實體

getInstance() 方法是靜態的,這意味著它是一個類別方法

所以可以在任何地方呼叫它,呼叫的方法很簡單「Singleton.getInstance()」

就和存取全域變數一樣簡單,但是比全域變數多了一個優點:獨體可以進行拖延實體化

 

singleton  

 

在討論Singleton pattern時,通常我們都會討論到Singleton pattern加上多執行緒時的功能就有可能出現問題

為什麼呢? 假如程式是如下圖一樣執行,就會產生出2個物件

image_4  

那這個問題該如何解決呢?

singleton_2  

▲第一種解法就是加上synchronized關鍵字

迫使執行緒進入此方法前,要先等候別的執行緒離開此方法

也就是說,沒有兩個執行緒可以同時進入此方法

但是同步化會降低效率,因為只有第一次執行此方法時

才真正需要同步化,一旦設定好uniqueInstance變數,就不需要再同步化此方法了

singleton_3  

▲另外一種作法叫做「率先建立實體」,而不用拖延實體化的作法

這樣的方法保證安全,但比較浪費資源

singleton_4    

▲最後一種作法稱作「雙重檢查上鎖」

在getInstance的存取點方法的地方,我們建立了兩次的檢查實體的動作,

而第二個檢查實體必須Lock住uniqueInstance,確保他在這段時間內不會被修改!

 

而另一個改變是volatile關鍵字,這個關鍵字確保,當uniqueInstance變數被實體化的時候,

多個執行緒處理uniqueInstance的作法是正確的。

若效能是你關心的重點,那這個作法可以幫你大大減少getInstance的時間耗費。

 

arrow
arrow

    Mark Zhang 發表在 痞客邦 留言(0) 人氣()