獨一無二的單例模式

2021-09-20 03:18:58 字數 2326 閱讀 3614

單例模式被定義為:確保乙個類只有乙個例項,並提供乙個全域性訪問點。

單例模式使得乙個類只能有唯一的乙個例項,這意味著不能再使用new關鍵字建立物件,因為一旦可以被new,就可以被多次new。

問題1:如何保證乙個類只有乙個例項?

問題2:不能使用new如何獲取物件?

這兩個問題的答案非常簡單:

由於new物件會呼叫構造方法,所以只需要將構造方法定義為private(雖然很少這麼幹,但單例模式必須如此);這樣建立物件的任務只能在類中完成;

定義明確指出需要提供乙個全域性訪問點,意思就是需要拿到類中定義的物件,可以使用static方法,以下是經典單例模式的實現

public class singleton 

public static singleton getinstance()

return singleton;}}

單例模式沒有複雜的類圖結構,而且**非常簡單,但仍然需要注意一些細節:

構造方法私有化,只有類中才可以呼叫構造方法

全域性訪問點被定義為static方法,直接通過類名就可以呼叫

在getinstance()中,if(singleton==null)和靜態成員singleton配合組成了單例模式的核心,只有第一次呼叫getinstance()時,其中的**會全部執行。singleton只會被初始化一次。

如果不需要singleton的例項,永遠不會建立它的例項,這稱為延遲例項化(lazy instance)

單例模式的類圖如下:

確實,目前為止單例模式非常簡單;可是能夠完全滿足單例的需求嗎?還需要看一看在多執行緒下的單例模式。

單例模式在多執行緒下可能會建立多個物件而違反單例模式的原則

如圖所示,如下執行緒a進入if語句但還未建立物件是,因為某些原因導致a發生了阻塞,由於a還沒有來得及建立物件,所以執行緒b又進入了if語句,建立了乙個例項,b執行完成後,a繼續執行,雖然此時以及singleton已經不為空,但是a依然會建立物件,此時就破壞了單例模式的原則。

為了保證在多執行緒環境下能夠正確的使用單例模式,可以採用三種方法:

同步方法「急切」建立例項雙重加鎖不需要做任何改變,只需要在getinstance()方法前假設synchronized關鍵字

public class singleton 

* 同步方法實現多執行緒下的單例模式

* @return

*/public static synchronized singleton getinstance()

return singleton;}}

同步方法非常簡單粗暴,帶來的問題也很明顯:降低效能,每一次呼叫全域性訪問點,都會是一種累贅。

急切建立例項的意思是在類載入靜態singleton時就建立出例項,這樣無論如何都不可能再有第二個例項產生,但這樣就失去了延遲例項化的好處。

public class singleton 	

/*** 急切建立例項實現多執行緒下的單例模式

*/public static singleton getinstance()

}

這種方法在jvm載入類時即建立出例項,同時也簡化了getinstance()方法

雙重加鎖也是採用同步的方法,但是會減少同步的使用以提高效能。

public class singleton 

/*** 雙重鎖實現多執行緒下的單例模式

* @return

*/public static singleton getinstance() }}

return singleton;}}

同步**塊寫在if中,意思是如果singleton沒有例項化才進行同步;

volatile關鍵字能夠保證一旦singleton被初始化後,多執行緒下可以正確的處理它。

單例模式確保程式中乙個類最多只能有乙個例項

單例模式提高乙個全域性訪問點獲取唯一的例項

單例模式依賴於私有構造器,乙個靜態變數和乙個靜態方法

單例模式再多執行緒環境下可能失效,需要使用一定的改進方法

單例模式 建立獨一無二的物件

單例模式 singleton pattern 用來建立獨一無二的,只能有乙個例項的物件的入場券。作用 有些物件我們只需要乙個,比如 執行緒池 快取 對話方塊 處理偏好設定 登錄檔等物件,這些物件只能有乙個例項,如果製造出多個例項,就會導致很多問題產生,例如 程式行為異常 資源使用過量 或者是不一致的...

單例模式製造獨一無二的物件

為什麼不用靜態全域性變數呢?如果將物件賦值給全域性變數,那麼你必須在程式一開始就建立物件,非常消耗資源。利用單例模式,就可以在需要的時候才建立物件。另外全域性變數可能指向多個物件,這違反了例項唯一性。單例模式確保乙個類有且僅有乙個例項,並提供乙個全域性變數。類圖如下 單例模式典型例子強調三點 1 定...

設計模式系列 搞懂單例模式,我獨一無二

單例模式的定義 乙個類只有乙個例項,且該類能自行建立這個例項,並提供乙個訪問該單例的全域性訪問點。屬於建造型模式。單例模式的實現 餓漢式單例 類載入的時候即初始化並建立單例物件。適用於單例物件較少的情況。public class hungrysingleton public static hungr...