通俗易懂 一天乙個設計模式 單例模式

2021-10-08 00:07:14 字數 2528 閱讀 8525

前言

正文----什麼是單例模式?

----------有趣的小豬搶蛋糕

----------單例模式

?想看通俗易懂的工廠模式戳這裡。

設計模式代表了前人的最佳實踐,在水平達到了一定的層級之後,總是要接觸設計模式的。本文旨在使用通俗易懂的例子,幫助初學者理解單例模式。

單例模式顧名思義,乙個類僅能有乙個例項。所以他的物件不能被手動例項化(就無法保證只有乙個例項),而是由該類建立,並提供訪問例項物件的方法。

從前有一群笨笨的小豬?,總共100頭吧。

小豬的飲食很規律,吃飯前,如果桌子上沒有蛋糕,第一頭小豬申請100個小蛋糕放到桌子上,然後自己拿乙個。如果桌子上有蛋糕,其他小豬隻需要拿蛋糕就可以了,不需要再次申請。

我們從小豬搶蛋糕的故事來理解單例模式,飼養員做蛋糕的方式(懶惰或者勤快)對應我們兩種方法(懶漢模式和餓漢模式)。

懶漢模式:(需要建立類我才建立,不需要建立我就不建立)

public

class

cake

;//構造方法

public

static cake gethundredcake()

return cake;

}}

餓漢模式: (不管你需不需要,我都先建立乙個例項物件)

public

class

cake

;//構造方法

public

static cake gethundredcake()

}

在這裡,執行緒就是我們的小豬,同時爭搶的情況就是多執行緒衝突,不難發現餓漢模式對應飼養員第四天的情況,在餓漢模式下,物件例項已經被提前建立,犧牲了記憶體空間,但是解決了執行緒安全的問題,是執行緒安全的實現。

現在我們看一下懶漢模式,不難發現懶漢模式對應飼養員第一天的情況,在多執行緒情況下,多個執行緒同時申請建立例項,這樣就建立了多個物件例項,不符合我們的單例設計模式。

比如下面的**

if

(cake == null)

第乙個執行緒產生了乙個cake引用物件,但此時還沒有建立例項物件(沒有呼叫new cake()方法),然後後面的執行緒都突破了判斷語句的屏障,都來例項化物件,對應於小豬同時申請蛋糕。

有人可能說為什麼不先呼叫new cake()方法,這裡設計到乙個指令重排的問題,感興趣的朋友檢視相關資料。

那怎麼解決執行緒不安全的問題呢?參考飼養員第二天的做法,可以使用synchronized關鍵字。

我們在拿蛋糕的時候進行排隊處理,(對獲取例項方法進行加鎖)

public

class

cake

;//構造方法

public

static

synchronized cake gethundredcake()

return cake;

}}

我們也說了,這種方式雖然能保證執行緒安全,但是效率不是很高。

對於提高效率的方法,我們參考飼養員第三天的做法,只對申請蛋糕(建立例項)進行排隊(加鎖),對於拿蛋糕不做限制,(細化鎖的粒度,只對建立例項的步驟加鎖)

public

class

cake

;//構造方法

public

static cake gethundredcake()

}return cake;

}}

但是現在這樣真的可以執行緒安全了嗎?

我們可以看到在物件被例項化之前,可能有多個執行緒突破了判斷語句的屏障,我們現在加的同步鎖只能保證這幾個執行緒是依次建立例項物件,並不能保證單例。

(我們繼續參考飼養員第四天的做法-------第乙個小豬申請完,此時桌子上並沒有蛋糕(飼養員太懶了),其他小豬還會繼續申請,這時候飼養員會告訴剩下的小豬蛋糕正在做,不用繼續申請了。)

我們需要告訴其他小豬,蛋糕正在做,怎麼告訴呢?

這裡我們可以在鎖內部(蛋糕放到桌子之前),再加乙個判斷(告訴其他小豬不必申請),**如下:

public

class

cake

;//構造方法

public

static cake gethundredcake()

}return cake;

}}

我們可以看到現在有了兩個判斷語句和乙個同步鎖,我們一般稱為

雙重檢查鎖double-checked locking

值得注意的是我們的coke物件前加了volatile關鍵字修飾,該關鍵字能夠防止指令重排以及保證內記憶體可見性,加上他後可以更加保證執行緒安全,感興趣的朋友檢視相關資料。

一天乙個設計模式 單例模式

1.餓漢模式public class sprivate static s s news public static s get 執行緒安全,載入時就初始化,根據需求來,此種用法最簡單2.懶漢模式public class sprivate static s s public static s get ...

設計模式之單例模式(通俗易懂,超詳細)

簡單來說單例模式就是指在記憶體中只會建立且僅建立一次物件的設計模式,當程式中其他地方需要使用到該物件的相同功能時,都會呼叫建立好的這乙個,不會再額外建立例項,這樣做的好處就是避免過多的建立相同作用的物件使得記憶體浪費。在單例模式中主要分為兩類,分別是懶漢式和餓漢式 懶漢式 在程式呼叫時才建立例項 餓...

一天乙個設計模式 建造者模式

這個模式和工廠模式很像,建造者 builder 模式和工廠模式的關注點不同 建造者模式注重零部件的組裝過程,而工廠方法模式更注重零部件的建立過程,但兩者可以結合使用。舉個栗子,stringbuilder public class abstractstringbuilder char c privat...