單例模式 DoubleCheck

2021-09-25 16:32:13 字數 1843 閱讀 8439

1.單例模式理解:是為了滿足一些場景,乙個物件只能建立乙個例項物件的場景。

流程:1.構造方法私有化,

2.宣告物件 位靜態

3.類方法返回例項化後的物件。

2.將單例模式分為兩類 懶漢式和餓漢式:

懶漢式:特點在定義singleton是就new

public class singleton

public static singleton newinstance()

}

優點:簡單,而且保證了執行緒安全,不管有多少個執行緒訪問都只返回乙個singleton例項化物件

餓漢式單例模式:

1.普通

public class singleton

public static singleton newinstance()

return singleton;

}}

執行緒不安全:if判斷確實可以保證只建立乙個singleton的例項物件。

但是在多執行緒併發場景下,由於沒有加鎖,多個執行緒可能都會進入到if中,那麼這些執行緒就可以進行物件例項化操作產生多個物件。

if(singleton==null)
雙層檢驗鎖單例模式:

public class singleton

public static singleton newinstance()}}

return singleton;//3

}}

按照上面的注釋:來分析上面的**:

1.在呼叫類方法newinstance的時候所有執行緒都可以進入//1中

2.多個執行緒中只有乙個執行緒會拿到鎖 進入同步**塊

3.拿到鎖後要再次判斷當前物件引用是否指向例項,因為在這個執行緒之前還會有別的執行緒拿到鎖執行同步**塊。

到此流程基本結束:還有幾個問題:

1.singleton為什麼要用volatile修飾?

首先,synchronized 保證了只有乙個執行緒對singleton進行例項操作,但是操作的物件是引用資料型別,換句話說該操作不是原子的。那麼久可能發生指令重排。

正常情況:例項化物件的流程:

1.在堆上開闢空間

2.屬性初始化

3.將棧上空間指向堆。

正常是1——>2——>3

但是如果沒有volatile關鍵字就可能發生指令重排:

假設 1——>3——>2

如果沒有屬性的話沒有問題,

一旦有了屬性,假設現在有兩個屬性:

name=「hahaha」,

age=12;

由於3步驟先執行,singleton已經不為空了,

當有新的執行緒嘗試獲取singleton例項,到了外層判斷,直接返回。

導致的結果就是,有能屬性還沒有來的及初始化就直接返回了,或者初始化了name..

2.為什麼要有雙重if判斷:

內部的if是保證只有乙個singleton例項化物件被建立。

外層的if實際上是為了保證效能:

當singleton已經被建立了,不進入內部,直接返回。

可以把這種機制:當做乙個限量發售的鞋,

把多執行緒當做在排隊等待鞋的人。

當乙個人進入後買了這雙鞋 實際上已經沒有這雙鞋了

通常做法是在門口立乙個牌子,鞋已經售空 人看到這個牌子就可以直接走了

相當於外部的i f)。

如果沒有這個牌子,外面的人就不知道鞋已經賣完,還在不斷排隊進入鞋店,浪費資源

單例模式與double check

本文主要是講double check,通常double check比較少用,一般是在高併發的情況下。但是建議大家寫單例的時候都用上。單例模式分兩種 餓漢式與懶漢式,餓漢式是指在類載入時就進行例項化,而懶漢式是指在使用時才進行例項化。如下 餓漢式 public class singleton publ...

設計模式單例模式之double check

設計模式之雙重判定鎖 double check 下面列出乙個比較常用的也是我個人最喜歡的一種在多執行緒的情況下,又能滿足lazy loading,效率又高的一種單例模式的寫法 class singleton 在這可能有些小夥伴會問這個volatile這個是幹啥的,給出答案 volatile這個關鍵字...

double check單例模式是否執行緒安全

要求 1.執行緒安全 2.效率高 double check優化了每次呼叫加鎖的開銷。static t m pinstance static t instance void void omutex.release return m pinstance new 操作符不是原子操作。new 操作符的執行過...