Singleton Pattern : 確保一個類別只有一個實體,並給它一個存取的全域點(global point)
把某個類別設計成自己管理的一個Singleton instance,同時也避免其他類別再產生自己的instance
想取得Singleton instance,透過Singleton class是唯一的途徑
▲Singleton class diagram
uniqueInstance 資料成員紀錄了唯一的實體
getInstance() 方法是靜態的,這意味著它是一個類別方法
所以可以在任何地方呼叫它,呼叫的方法很簡單「Singleton.getInstance()」
就和存取全域變數一樣簡單,但是比全域變數多了一個優點:獨體可以進行拖延實體化
在討論Singleton pattern時,通常我們都會討論到Singleton pattern加上多執行緒時的功能就有可能出現問題
為什麼呢? 假如程式是如下圖一樣執行,就會產生出2個物件
那這個問題該如何解決呢?
▲第一種解法就是加上synchronized關鍵字
迫使執行緒進入此方法前,要先等候別的執行緒離開此方法
也就是說,沒有兩個執行緒可以同時進入此方法
但是同步化會降低效率,因為只有第一次執行此方法時
才真正需要同步化,一旦設定好uniqueInstance變數,就不需要再同步化此方法了
▲另外一種作法叫做「率先建立實體」,而不用拖延實體化的作法
這樣的方法保證安全,但比較浪費資源
▲最後一種作法稱作「雙重檢查上鎖」
在getInstance的存取點方法的地方,我們建立了兩次的檢查實體的動作,
而第二個檢查實體必須Lock住uniqueInstance,確保他在這段時間內不會被修改!
而另一個改變是volatile關鍵字,這個關鍵字確保,當uniqueInstance變數被實體化的時候,
多個執行緒處理uniqueInstance的作法是正確的。
若效能是你關心的重點,那這個作法可以幫你大大減少getInstance的時間耗費。