如何正確地寫出單例模式

2021-08-28 16:07:40 字數 1058 閱讀 4399

發表於 2014-08-28   |   分類於 程式設計   |     |   閱讀次數 50513

單例模式算是設計模式中最容易理解,也是最容易手寫**的模式了吧。但是其中的坑卻不少,所以也常作為面試題來考。本文主要對幾種單例寫法的整理,並分析其優缺點。很多都是一些老生常談的問題,但如果你不知道如何建立乙個執行緒安全的單例,不知道什麼是雙檢鎖,那這篇文章可能會幫助到你。

當被問到要實現乙個單例模式時,很多人的第一反應是寫出如下的**,包括教科書上也是這樣教我們的。

public class singleton

public static singleton getinstance()  

public static singleton getsingleton()

public static singleton getinstance()

public static final singleton getinstance() {

return singletonholder.instance;

這種寫法仍然使用jvm本身機制保證了執行緒安全問題;由於 singletonholder 是私有的,除了 getinstance() 之外沒有辦法訪問它,因此它是懶漢式的;同時讀取例項的時候不會進行同步,沒有效能缺陷;也不依賴 jdk 版本。

用列舉寫單例實在太簡單了!這也是它最大的優點。下面這段**就是宣告列舉例項的通常做法。

public enum easysingleton{

instance;

我們可以通過easysingleton.instance來訪問例項,這比呼叫getinstance()方法簡單多了。建立列舉預設就是執行緒安全的,所以不需要擔心double checked locking,而且還能防止反序列化導致重新建立新的物件。但是還是很少看到有人這樣寫,可能是因為不太熟悉吧。

就我個人而言,一般情況下直接使用餓漢式就好了,如果明確要求要懶載入(lazy initialization)會傾向於使用靜態內部類,如果涉及到反序列化建立物件時會試著使用列舉的方式來實現單例。

如何正確地部署防火牆?

防火牆在實際的部署應用過程當中,經常部署在閘道器的位置,也就是經常部署在網內和網外的乙個 中間分隔點 上,而就是在這樣乙個部署的環境中,也還存在著多種方式,且存在著許多 陷阱 本文將對幾種方式進行分析。請閱讀全文 防火牆在實際的部署應用過程當中,經常部署在閘道器的位置,也就是經常部署在網內和網外的乙...

如何正確地在MDK中使用關鍵

筆者在做移植時,將embest ide環境下的例程移到realview mdk的過程中,曾經遇到這樣乙個問題 在生成工程時,編譯全部通過,但在鏈結時提示許多符號未定義!如果讀者也遇到過這個問題,請繼續看下去,如果鏈結時提示未定義的變數是一些內聯函式 即使用了關鍵字 inline 那麼就是筆者遇到的問...

如何正確地顯示隨機訊息?讀後總結

背景 有個單詞表,隨機顯示3個單詞 建表語句與初始化語句 mysql create tablewords idint 11 not null auto increment,wordvarchar 64 default null,primary key id engine innodb delimit...