1. 程式人生 > >軟體設計模式與體系結構--單例模式

軟體設計模式與體系結構--單例模式

單例模式例項

餓漢模式和懶漢模式區別

一.懶漢模式
只有在自身需要的時候才會行動,從來不知道及早做好準備,它在需要物件的時候,才判斷是否已有物件,如果沒有就立即建立一個物件,然後返回,如果已有物件就不再建立,立即返回。懶漢模式只在外部物件第一次請求例項的時候才去建立。程式碼如下:
1>不加鎖情況

2>加鎖情況
在這裡插入圖片描述

加鎖的原因

一般情況不加鎖並沒有任何問題,但是在多執行緒併發執行的時候就很容易出現問題,第一個執行緒在判斷newInstance==null時,還沒有new出例項時,第二個執行緒也進來,判斷的newInstance也是null,然後也會new出例項,這就不是我們想要的單例模式了,所以就需要加鎖,使用synchronized關鍵字.

兩者區別

懶漢模式:在類載入的時候不被初始化。
餓漢模式:在類載入時就完成了初始化,但是載入比較慢,獲取物件比較快。
餓漢模式是執行緒安全的,在類建立好一個靜態物件提供給系統使用,懶漢模式在建立物件時不加上synchronized,會導致物件的訪問不是執行緒安全的

二.餓漢模式
從名字去理解,它很餓,所以在載入類的時候,就進行初始化了。當你呼叫的時候,直接呼叫就好了。
程式碼如下:

訪問網站,百度算不算是單例模式

單例模式定義是保證一個類僅有一個例項,並提供一個訪問它的全域性訪問點。
而訪問網站,百度,可以同時通過多個地方登陸或者進入,它們的訪問點有多個,所以不是單例模式。

loDH方式/或者技術 實現單例模式

餓漢式單例類不能實現延遲載入,不管將來用不用始終佔據記憶體;懶漢式單例類執行緒安全控制煩瑣,而且效能受影響。可見,無論是餓漢式單例還是懶漢式單例都存在這樣那樣的問題,有沒有一種方法,能夠將兩種單例的缺點都克服,而將兩者的優點合二為一呢?答案是:Yes!下面我們來學習這種更好的被稱之為Initialization Demand Holder (IoDH)的技術。

在IoDH中,我們在單例類中增加一個靜態(static)內部類,在該內部類中建立單例物件,再將該單例物件通過getInstance()方法返回給外部使用,實現程式碼如下所示:
在這裡插入圖片描述
編譯並執行上述程式碼,執行結果為:true,即建立的單例物件s1和s2為同一物件。由於靜態單例物件沒有作為Singleton的成員變數直接例項化,因此類載入時不會例項化Singleton,第一次呼叫getInstance()時將載入內部類HolderClass,在該內部類中定義了一個static型別的變數instance,此時會首先初始化這個成員變數,由Java虛擬機器來保證其執行緒安全性,確保該成員變數只能初始化一次。由於getInstance()方法沒有任何執行緒鎖定,因此其效能不會造成任何影響。

通過使用IoDH,我們既可以實現延遲載入,又可以保證執行緒安全,不影響系統性能,不失為一種最好的Java語言單例模式實現方式(其缺點是與程式語言本身的特性相關,很多面向物件語言不支援IoDH)。